diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..769644890 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +# Ignore everything +* + +# ...even if they are in subdirectories +!*/ + +# But not these files... +!/.gitignore +!/ReadMe.md + + +# EVS +!modules/evs/fsw/**/** +!modules/core_api/fsw/inc/cfe_evs* +!modules/core_private/fsw/inc/cfe_evs_log_typedef.h +!modules/evs/CMakeLists.txt + +# FS +!cfe_fs* +!modules/fs/fsw/* +!modules/fs/CMakeLists.txt diff --git a/README.md b/README.md index 7be7449c5..d9187d90e 100644 --- a/README.md +++ b/README.md @@ -1 +1,24 @@ -# cFE \ No newline at end of file +## cFS-Caelum Review: CFS-41 + +This branch is meant for the cFS-Caelum code review of Event (EVS), File Services (FS), The review designation is "CFS-41" + + +The corresponding, fully-working cFE instance matching the code in this branch can be found under the [cFE v7.0.0-rc1 tag](https://github.com/nasa/cFE/releases/tag/v7.0.0-rc1) + +### How to add your review comments + +Navigate to the ["files changed" tab](https://github.com/nasa/cFE/pull/1294/files) in the [nasa/cFE#1294](https://github.com/nasa/cFE/pull/1294) pull request. + + +github-review-instructions-1of2 + + +You can add comments on any line of code by hovering on the line number and clicking on the plus "+" sign. Once you're finished with the comment click on the green "Start Review" button. To add more comments, just click on the relevant line number in any file, type your comment, and click on "Add review comment". + + +github-review-instructions-2of2 + + If you need to take a break, or if you're done, click the green "Finish Review" button on the top right corner of the +page, add any overall or summarizing comments and click on "Submit Review". You can always return and add new comments using the same process. + +**Thank you!** diff --git a/modules/core_api/eds/cfe_fs.xml b/modules/core_api/eds/cfe_fs.xml new file mode 100644 index 000000000..da85a5912 --- /dev/null +++ b/modules/core_api/eds/cfe_fs.xml @@ -0,0 +1,165 @@ + + + + + + + + + + + Executive Services Exception/Reset Log File which is generated in response to a + \link #CFE_ES_WRITE_ERLOG_CC \ES_WRITEERLOG2FILE \endlink + command. + + + + + Executive Services System Log File which is generated in response to a + \link #CFE_ES_WRITE_SYSLOG_CC \ES_WRITESYSLOG2FILE \endlink + command. + + + + + Executive Services Information on All Applications File which is generated in response to a + \link #CFE_ES_QUERY_ALL_CC \ES_WRITEAPPINFO2FILE \endlink + command. + + + + + Executive Services Performance Analyzer Data File which is generated in response to a + \link #CFE_ES_PERF_STOPDATA_CC \ES_STOPLADATA \endlink + command. + + + + + Executive Services Shell Response Data File which is generated in response to a + \link #CFE_ES_SHELL_CMD_CC \ES_SHELL \endlink + command. + + + + + Executive Services Critical Data Store Registry Dump File which is generated in response to a + \link #CFE_ES_DUMP_CDS_REG_CC \ES_DUMPCDSREG \endlink + command. + + + + + Table Services Registry Dump File which is generated in response to a + \link #CFE_TBL_DUMP_REG_CC \TBL_WRITEREG2FILE \endlink + command. + + + + + Table Services Table Image File which is generated either on the ground or in response to a + \link #CFE_TBL_DUMP_CC \TBL_DUMP \endlink command. + + + + + Event Services Application Data Dump File which is generated in response to a + \link #CFE_EVS_FILE_WRITE_APP_DATA_CC \EVS_WRITEAPPDATA2FILE \endlink + command. + + + + + Event Services Local Event Log Dump File which is generated in response to a + \link #CFE_EVS_FILE_WRITE_LOG_DATA_CC \EVS_WRITELOG2FILE \endlink + command. + + + + + Software Bus Pipe Data Dump File which is generated in response to a + \link #CFE_SB_SEND_PIPE_INFO_CC \SB_WRITEPIPE2FILE \endlink + command. + + + + + Software Bus Message Routing Data Dump File which is generated in response to a + \link #CFE_SB_SEND_ROUTING_INFO_CC \SB_WRITEROUTING2FILE \endlink + command. + + + + + Software Bus Message Mapping Data Dump File which is generated in response to a + \link #CFE_SB_SEND_MAP_INFO_CC \SB_WRITEMAP2FILE \endlink + command. + + + + + Executive Services Query All Tasks Data File which is generated in response to a + \link #CFE_ES_QUERY_ALL_TASKS_CC \ES_WRITETASKINFO2FILE \endlink + command. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/core_api/fsw/inc/cfe_evs.h b/modules/core_api/fsw/inc/cfe_evs.h new file mode 100644 index 000000000..b6c8f6b1b --- /dev/null +++ b/modules/core_api/fsw/inc/cfe_evs.h @@ -0,0 +1,331 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/** + * @file + * + * Title: Event Services API Application Library Header File + * + * Purpose: + * Unit specification for Event services library functions and macros. + * + * Design Notes: + * + * References: + * Flight Software Branch C Coding Standard Version 1.0a + */ + +#ifndef CFE_EVS_H +#define CFE_EVS_H + +/********************************** Include Files ************************************/ +#include "common_types.h" /* Basic data types */ +#include "cfe_error.h" +#include "cfe_evs_api_typedefs.h" +#include "cfe_es_api_typedefs.h" +#include "cfe_time_api_typedefs.h" + +/* +** Utility macros to make for simpler/more compact/readable code. +*/ +#define CFE_EVS_Send(E, T, ...) CFE_EVS_SendEvent((E), CFE_EVS_EventType_##T, __VA_ARGS__) +#define CFE_EVS_SendDbg(E, ...) CFE_EVS_Send(E, DEBUG, __VA_ARGS__) +#define CFE_EVS_SendInfo(E, ...) CFE_EVS_Send(E, INFORMATION, __VA_ARGS__) +#define CFE_EVS_SendErr(E, ...) CFE_EVS_Send(E, ERROR, __VA_ARGS__) +#define CFE_EVS_SendCrit(E, ...) CFE_EVS_Send(E, CRITICAL, __VA_ARGS__) + +/****************** Function Prototypes **********************/ + +/** @defgroup CFEAPIEVSReg cFE Registration APIs + * @{ + */ + +/** +** \brief Register an application for receiving event services +** +** \par Description +** This routine registers an application with event services and allocates/initializes +** the internal data structures used to support this application's events. An application +** may not send events unless it has called this routine. The routine also accepts a filter +** array structure for applications requiring event filtering. In the current implementation +** of the EVS, only the binary filtering scheme is supported. See section TBD of the cFE +** Application Programmer's Guide for a description of the behavior of binary filters. +** Applications may call #CFE_EVS_Register more than once, but each call will wipe out all +** filters registered by previous calls (filter registration is NOT cumulative). +** +** \par Assumptions, External Events, and Notes: +** Note: Event filters can be added, deleted or modified by ground commands. All filtering +** schemes include a default setting that results in no filtering (such as #CFE_EVS_NO_FILTER +** for binary filters). +** +** Filter Scheme: Binary
+** Code: CFE_EVS_EventFilter_BINARY
+** Filter Structure: +** \code +** typedef struct CFE_EVS_BinFilter { +** uint16 EventID, +** uint16 Mask ; +** } CFE_EVS_BinFilter_t; +** \endcode +** +** \param[in] Filters Pointer to an array of event message filters, or NULL if no filtering is desired. +** The structure of an event message filter depends on the FilterScheme selected. +** (see Filter Schemes mentioned above) +** +** \param[in] NumFilteredEvents The number of event message filters included in this call. This must be less than +** or equal to the maximum number of events allowed per application +*(#CFE_PLATFORM_EVS_MAX_EVENT_FILTERS). +** +** \param[in] FilterScheme The event filtering scheme that this application will use. For the first +** implementation of the event services, only filter type #CFE_EVS_EventFilter_BINARY +** will be supported. +** +** \return Execution status below or from #CFE_ES_GetAppID, see \ref CFEReturnCodes +** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS +** \retval #CFE_EVS_APP_FILTER_OVERLOAD \copybrief CFE_EVS_APP_FILTER_OVERLOAD +** \retval #CFE_EVS_UNKNOWN_FILTER \copybrief CFE_EVS_UNKNOWN_FILTER +** \retval #CFE_EVS_APP_ILLEGAL_APP_ID \copybrief CFE_EVS_APP_ILLEGAL_APP_ID +** +** \sa #CFE_EVS_Unregister +** +**/ +CFE_Status_t CFE_EVS_Register(const void *Filters, /* Pointer to an array of filters */ + uint16 NumFilteredEvents, /* How many elements in the array? */ + uint16 FilterScheme); /* Filtering Algorithm to be implemented */ + +/** +** \brief Cleanup internal structures used by the event manager for the calling Application. +** +** \par Description +** This routine un-registers the calling application from receiving event services +** and removes and deletes the calling applications filters and counters from the +** internal event service filter and counter tables if registered. Applications +** must call this routine as part of their orderly shutdown process. +** +** \par Assumptions, External Events, and Notes: +** None +** +** \return Execution status below or from #CFE_ES_GetAppID/#CFE_ES_PutPoolBuf, see \ref CFEReturnCodes +** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS +** \retval #CFE_EVS_APP_NOT_REGISTERED \copybrief CFE_EVS_APP_NOT_REGISTERED +** \retval #CFE_EVS_APP_ILLEGAL_APP_ID \copybrief CFE_EVS_APP_ILLEGAL_APP_ID +** +** \sa #CFE_EVS_Register +** +**/ +CFE_Status_t CFE_EVS_Unregister(void); +/**@}*/ + +/** @defgroup CFEAPIEVSSend cFE Send Event APIs + * @{ + */ + +/** +** \brief Generate a software event. +** +** \par Description +** This routine generates a software event message. If the EventID is not filtered, +** the event will be sent as a software bus message, optionally logged in the local +** event log, and optionally sent as an ASCII text string out the enabled output port(s). +** +** \par Assumptions, External Events, and Notes: +** This API only works within the context of a registered application or core service. +** For messages outside the context of a registered appliction (for example early +** in app initialization or if registration fails) #CFE_ES_WriteToSysLog can be used +** for reporting. +** +** \param[in] EventID A numeric literal used to uniquely identify an application event. +** The \c EventID is defined and supplied by the application sending the event. +** +** \param[in] EventType A numeric literal used to classify an event, one of: +** \arg #CFE_EVS_EventType_DEBUG +** \arg #CFE_EVS_EventType_INFORMATION +** \arg #CFE_EVS_EventType_ERROR +** \arg #CFE_EVS_EventType_CRITICAL +** +** \param[in] Spec A pointer to a null terminated text string describing the output format +** for the event. This is the same type of format string used for the ANSI +** \c printf function. Nominally the post-conversion string is limited to 80 +** characters, but this limit is configurable through the parameter +** #CFE_MISSION_EVS_MAX_MESSAGE_LENGTH. Characters beyond the limit will be truncated. +** Do not use floating point conversions (%f, %e, %E, %g, and %G) in the format +** string unless your application will be running in a system that supports +** floating point arithmetic. Do not use non-printable characters (\\t, \\n, etc.) +** in the format string; they will mess up the formatting when the events are +** displayed on the ground system. +** +** \return Execution status, see \ref CFEReturnCodes +** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS +** \retval #CFE_EVS_APP_NOT_REGISTERED \copybrief CFE_EVS_APP_NOT_REGISTERED +** \retval #CFE_EVS_APP_ILLEGAL_APP_ID \copybrief CFE_EVS_APP_ILLEGAL_APP_ID +** +** \sa #CFE_EVS_SendEventWithAppID, #CFE_EVS_SendTimedEvent +** +**/ +CFE_Status_t CFE_EVS_SendEvent(uint16 EventID, uint16 EventType, const char *Spec, ...) OS_PRINTF(3, 4); + +/** +** \brief Generate a software event given the specified Application ID. +** +** \par Description +** This routine generates a software event message. If the EventID is not filtered, +** the event will be sent as a software bus message, optionally logged in the local +** event log, and optionally sent as an ASCII text string out the enabled output port(s). +** Note that this function should really only be used from within an API in order to +** preserve the context of an Application's event. In general, #CFE_EVS_SendEvent should be used. +** +** \par Assumptions, External Events, and Notes: +** The Application ID must correspond to a registered application or core service. +** For messages outside the context of a registered appliction (for example early +** in app initialization or if registration fails) #CFE_ES_WriteToSysLog can be used +** for reporting. +** +** \param[in] EventID A numeric literal used to uniquely identify an application event. +** The \c EventID is defined and supplied by the application sending the event. +** +** \param[in] EventType A numeric literal used to classify an event, one of: +** \arg #CFE_EVS_EventType_DEBUG +** \arg #CFE_EVS_EventType_INFORMATION +** \arg #CFE_EVS_EventType_ERROR +** \arg #CFE_EVS_EventType_CRITICAL +** +** \param[in] AppID The Application ID from which the event message should appear. +** +** \param[in] Spec A pointer to a null terminated text string describing the output format +** for the event. This is the same type of format string used for the ANSI +** \c printf function. Nominally the post-conversion string is limited to 80 +** characters, but this limit is configurable through the parameter +** #CFE_MISSION_EVS_MAX_MESSAGE_LENGTH. Characters beyond the limit will be truncated. +** Do not use floating point conversions (%f, %e, %E, %g, and %G) in the format +** string unless your application will be running in a system that supports +** floating point arithmetic. Do not use non-printable characters (\\t, \\n, etc.) +** in the format string; they will mess up the formatting when the events are +** displayed on the ground system. +** +** \return Execution status, see \ref CFEReturnCodes +** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS +** \retval #CFE_EVS_APP_NOT_REGISTERED \copybrief CFE_EVS_APP_NOT_REGISTERED +** \retval #CFE_EVS_APP_ILLEGAL_APP_ID \copybrief CFE_EVS_APP_ILLEGAL_APP_ID +** +** \sa #CFE_EVS_SendEvent, #CFE_EVS_SendTimedEvent +** +**/ +CFE_Status_t CFE_EVS_SendEventWithAppID(uint16 EventID, uint16 EventType, CFE_ES_AppId_t AppID, const char *Spec, ...) + OS_PRINTF(4, 5); + +/** +** \brief Generate a software event with a specific time tag. +** +** \par Description +** This routine is the same as #CFE_EVS_SendEvent except that the caller specifies the event time +** instead of having the EVS use the current spacecraft time. This routine should be used in +** situations where an error condition is detected at one time, but the event message is reported +** at a later time. +** +** \par Assumptions, External Events, and Notes: +** This API only works within the context of a registered application or core service. +** For messages outside the context of a registered appliction (for example early +** in app initialization or if registration fails) #CFE_ES_WriteToSysLog can be used +** for reporting. +** +** \param[in] Time The time to include in the event. This will usually be a time returned +** by the function #CFE_TIME_GetTime. +** +** \param[in] EventID A numeric literal used to uniquely identify an application event. +** The \c EventID is defined and supplied by the application sending the event. +** +** \param[in] EventType A numeric literal used to classify an event, one of: +** \arg #CFE_EVS_EventType_DEBUG +** \arg #CFE_EVS_EventType_INFORMATION +** \arg #CFE_EVS_EventType_ERROR +** \arg #CFE_EVS_EventType_CRITICAL +** +** \param[in] Spec A pointer to a null terminated text string describing the output format +** for the event. This is the same type of format string used for the ANSI +** \c printf function. Nominally the post-conversion string is limited to 80 +** characters, but this limit is configurable through the parameter +** #CFE_MISSION_EVS_MAX_MESSAGE_LENGTH. Characters beyond the limit will be truncated. +** Do not use floating point conversions (%f, %e, %E, %g, and %G) in the format +** string unless your application will be running in a system that supports +** floating point arithmetic. Do not use non-printable characters (\\t, \\n, etc.) +** in the format string; they will mess up the formatting when the events are +** displayed on the ground system. +** +** \return Execution status, see \ref CFEReturnCodes +** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS +** \retval #CFE_EVS_APP_NOT_REGISTERED \copybrief CFE_EVS_APP_NOT_REGISTERED +** \retval #CFE_EVS_APP_ILLEGAL_APP_ID \copybrief CFE_EVS_APP_ILLEGAL_APP_ID +** +** \sa #CFE_EVS_SendEvent, #CFE_EVS_SendEventWithAppID +** +**/ +CFE_Status_t CFE_EVS_SendTimedEvent(CFE_TIME_SysTime_t Time, uint16 EventID, uint16 EventType, const char *Spec, ...) + OS_PRINTF(4, 5); +/**@}*/ + +/** @defgroup CFEAPIEVSResetFilter cFE Reset Event Filter APIs + * @{ + */ + +/** +** \brief Resets the calling application's event filter for a single event ID. +** +** \par Description +** The effect of resetting an event filter depends on the filter scheme. +** The #CFE_EVS_EventFilter_BINARY scheme resets the filter counter for the specified Event ID. +** +** \par Assumptions, External Events, and Notes: +** None +** +** \param[in] EventID A numeric literal used to uniquely identify an application event. +** The \c EventID is defined and supplied by the application sending the event. +** +** \return Execution status below or from #CFE_ES_GetAppID, see \ref CFEReturnCodes +** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS +** \retval #CFE_EVS_APP_NOT_REGISTERED \copybrief CFE_EVS_APP_NOT_REGISTERED +** \retval #CFE_EVS_APP_ILLEGAL_APP_ID \copybrief CFE_EVS_APP_ILLEGAL_APP_ID +** +** \sa #CFE_EVS_ResetAllFilters +** +**/ +CFE_Status_t CFE_EVS_ResetFilter(int16 EventID); + +/** +** \brief Resets all of the calling application's event filters. +** +** \par Description +** This routine resets all the calling application's event filter counters to zero, providing a +** quick and convenient method for resetting event filters. +** +** \par Assumptions, External Events, and Notes: +** None +** +** \return Execution status below or from #CFE_ES_GetAppID, see \ref CFEReturnCodes +** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS +** \retval #CFE_EVS_APP_NOT_REGISTERED \copybrief CFE_EVS_APP_NOT_REGISTERED +** \retval #CFE_EVS_APP_ILLEGAL_APP_ID \copybrief CFE_EVS_APP_ILLEGAL_APP_ID +** +** \sa #CFE_EVS_ResetFilter +** +**/ +CFE_Status_t CFE_EVS_ResetAllFilters(void); +/**@}*/ + +#endif /* CFE_EVS_H */ diff --git a/modules/core_api/fsw/inc/cfe_evs_api_typedefs.h b/modules/core_api/fsw/inc/cfe_evs_api_typedefs.h new file mode 100644 index 000000000..eb787cdf2 --- /dev/null +++ b/modules/core_api/fsw/inc/cfe_evs_api_typedefs.h @@ -0,0 +1,67 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/** + * @file + * + * Title: Event Services API Application Library Header File + * + * Purpose: + * Unit specification for Event services library functions and macros. + * + * Design Notes: + * + * References: + * Flight Software Branch C Coding Standard Version 1.0a + */ + +#ifndef CFE_EVS_API_TYPEDEFS_H +#define CFE_EVS_API_TYPEDEFS_H + +/********************************** Include Files ************************************/ +#include "common_types.h" /* Basic data types */ +#include "cfe_evs_extern_typedefs.h" + +/** \name Common Event Filter Mask Values */ +/** \{ */ +#define CFE_EVS_NO_FILTER 0x0000 /**< \brief Stops any filtering. All messages are sent. */ +#define CFE_EVS_FIRST_ONE_STOP 0xFFFF /**< \brief Sends the first event. All remaining messages are filtered. */ +#define CFE_EVS_FIRST_TWO_STOP 0xFFFE /**< \brief Sends the first 2 events. All remaining messages are filtered. */ +#define CFE_EVS_FIRST_4_STOP 0xFFFC /**< \brief Sends the first 4 events. All remaining messages are filtered. */ +#define CFE_EVS_FIRST_8_STOP 0xFFF8 /**< \brief Sends the first 8 events. All remaining messages are filtered. */ +#define CFE_EVS_FIRST_16_STOP 0xFFF0 /**< \brief Sends the first 16 events. All remaining messages are filtered. */ +#define CFE_EVS_FIRST_32_STOP 0xFFE0 /**< \brief Sends the first 32 events. All remaining messages are filtered. */ +#define CFE_EVS_FIRST_64_STOP 0xFFC0 /**< \brief Sends the first 64 events. All remaining messages are filtered. */ +#define CFE_EVS_EVERY_OTHER_ONE 0x0001 /**< \brief Sends every other event. */ +#define CFE_EVS_EVERY_OTHER_TWO 0x0002 /**< \brief Sends two, filters one, sends two, filters one, etc */ +#define CFE_EVS_EVERY_FOURTH_ONE 0x0003 /**< \brief Sends every fourth event message. All others are filtered. */ +/** \} */ + +/****************** Structure Definitions *********************/ + +/** \brief Event message filter defintion structure */ +typedef struct CFE_EVS_BinFilter +{ + uint16 EventID; /**< \brief Numerical event identifier */ + uint16 Mask; /**< \brief Binary filter mask value */ + +} CFE_EVS_BinFilter_t; + +#endif /* CFE_EVS_API_TYPEDEFS_H */ diff --git a/modules/core_api/fsw/inc/cfe_evs_core_internal.h b/modules/core_api/fsw/inc/cfe_evs_core_internal.h new file mode 100644 index 000000000..694833da3 --- /dev/null +++ b/modules/core_api/fsw/inc/cfe_evs_core_internal.h @@ -0,0 +1,91 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/** + * @file + * + * Title: Event Services API Application Library Header File + * + * Purpose: + * Unit specification for Event services library functions and macros. + * + * Design Notes: + * + * References: + * Flight Software Branch C Coding Standard Version 1.0a + */ + +#ifndef CFE_EVS_CORE_INTERNAL_H +#define CFE_EVS_CORE_INTERNAL_H + +#include "common_types.h" +#include "cfe_es_extern_typedefs.h" + +/* + * The internal APIs prototyped within this block are only intended to be invoked from + * other CFE core apps. They still need to be prototyped in the shared header such that + * they can be called from other core modules, but applications should not call these. + */ + +/** @defgroup CFEAPIEVSCoreInternal cFE Internal Event Services APIs, internal to CFE core + * @{ + */ + +/*****************************************************************************/ +/** +** \brief Entry Point for cFE Core Application +** +** \par Description +** This is the entry point to the cFE EVS Core Application. +** +** \par Assumptions, External Events, and Notes: +** None +** +******************************************************************************/ +extern void CFE_EVS_TaskMain(void); + +/*****************************************************************************/ +/** +** \brief Initializes the cFE core module API Library +** +** \par Description +** Initializes the cFE core module API Library +** +** \par Assumptions, External Events, and Notes: +** -# This function MUST be called before any module API's are called. +** +******************************************************************************/ +extern int32 CFE_EVS_EarlyInit(void); + +/*****************************************************************************/ +/** +** \brief Removes EVS resources associated with specified Application +** +** \par Description +** This function is called by cFE Executive Services to cleanup after +** an Application has been terminated. It frees resources +** that have been allocated to the specified Application. +** +******************************************************************************/ +extern int32 CFE_EVS_CleanUpApp(CFE_ES_AppId_t AppId); + +/**@}*/ + +#endif /* CFE_EVS_CORE_INTERNAL_H */ diff --git a/modules/core_api/fsw/inc/cfe_evs_extern_typedefs.h b/modules/core_api/fsw/inc/cfe_evs_extern_typedefs.h new file mode 100644 index 000000000..6259b5b37 --- /dev/null +++ b/modules/core_api/fsw/inc/cfe_evs_extern_typedefs.h @@ -0,0 +1,179 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/** + * @file + * + * Declarations and prototypes for cfe_evs_extern_typedefs module + */ + +#ifndef CFE_EVS_EXTERN_TYPEDEFS_H +#define CFE_EVS_EXTERN_TYPEDEFS_H + +/* This header may be generated from an EDS file, + * tools are available and the feature is enabled */ +#ifdef CFE_EDS_ENABLED_BUILD + +/* Use the EDS generated version of these types */ +#include "cfe_evs_eds_typedefs.h" + +#else +/* Use the local definitions of these types */ + +#include "common_types.h" + +/** + * @brief Label definitions associated with CFE_EVS_MsgFormat_Enum_t + */ +enum CFE_EVS_MsgFormat +{ + + /** + * @brief Short Format Messages + */ + CFE_EVS_MsgFormat_SHORT = 0, + + /** + * @brief Long Format Messages + */ + CFE_EVS_MsgFormat_LONG = 1 +}; + +/** + * @brief Identifies format of log messages + * + * @sa enum CFE_EVS_MsgFormat + */ +typedef uint8 CFE_EVS_MsgFormat_Enum_t; + +/** + * @brief Label definitions associated with CFE_EVS_LogMode_Enum_t + */ +enum CFE_EVS_LogMode +{ + + /** + * @brief Overwrite Log Mode + */ + CFE_EVS_LogMode_OVERWRITE = 0, + + /** + * @brief Discard Log Mode + */ + CFE_EVS_LogMode_DISCARD = 1 +}; + +/** + * @brief Identifies handling of log messages after storage is filled + * + * @sa enum CFE_EVS_LogMode + */ +typedef uint8 CFE_EVS_LogMode_Enum_t; + +/** + * @brief Label definitions associated with CFE_EVS_EventType_Enum_t + */ +enum CFE_EVS_EventType +{ + + /** + * @brief Events that are intended only for debugging, not nominal operations + */ + CFE_EVS_EventType_DEBUG = 1, + + /** + * @brief Events that identify a state change or action that is not an error + */ + CFE_EVS_EventType_INFORMATION = 2, + + /** + * @brief Events that identify an error but are not catastrophic (e.g. - bad command + */ + CFE_EVS_EventType_ERROR = 3, + + /** + * @brief Events that identify errors that are unrecoverable autonomously + */ + CFE_EVS_EventType_CRITICAL = 4 +}; + +/** + * @brief Identifies type of event message + * + * @sa enum CFE_EVS_EventType + */ +typedef uint16 CFE_EVS_EventType_Enum_t; + +/** + * @brief Label definitions associated with CFE_EVS_EventFilter_Enum_t + */ +enum CFE_EVS_EventFilter +{ + + /** + * @brief Binary event filter + */ + CFE_EVS_EventFilter_BINARY = 0 +}; + +/** + * @brief Identifies event filter schemes + * + * @sa enum CFE_EVS_EventFilter + */ +typedef uint8 CFE_EVS_EventFilter_Enum_t; + +/** + * @brief Label definitions associated with CFE_EVS_EventOutput_Enum_t + */ +enum CFE_EVS_EventOutput +{ + + /** + * @brief Output Port 1 + */ + CFE_EVS_EventOutput_PORT1 = 1, + + /** + * @brief Output Port 2 + */ + CFE_EVS_EventOutput_PORT2 = 2, + + /** + * @brief Output Port 3 + */ + CFE_EVS_EventOutput_PORT3 = 3, + + /** + * @brief Output Port 4 + */ + CFE_EVS_EventOutput_PORT4 = 4 +}; + +/** + * @brief Identifies event output port + * + * @sa enum CFE_EVS_EventOutput + */ +typedef uint8 CFE_EVS_EventOutput_Enum_t; + +#endif /* CFE_EDS_ENABLED_BUILD */ + +#endif /* CFE_EVS_EXTERN_TYPEDEFS_H */ diff --git a/modules/core_api/fsw/inc/cfe_fs.h b/modules/core_api/fsw/inc/cfe_fs.h new file mode 100644 index 000000000..6bca3f5c4 --- /dev/null +++ b/modules/core_api/fsw/inc/cfe_fs.h @@ -0,0 +1,344 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/** + * @file + * + * Purpose: cFE File Services (FS) library API header file + * + * Author: S.Walling/Microtel + * + */ + +#ifndef CFE_FS_H +#define CFE_FS_H + +/* +** Required header files... +*/ +#include "common_types.h" +#include "osconfig.h" +#include "cfe_platform_cfg.h" +#include "cfe_error.h" +#include "cfe_fs_api_typedefs.h" +#include "cfe_fs_extern_typedefs.h" + +/** @defgroup CFEAPIFSHeader cFE File Header Management APIs + * @{ + */ + +/*****************************************************************************/ +/** +** \brief Read the contents of the Standard cFE File Header +** +** \par Description +** This API will fill the specified #CFE_FS_Header_t variable with the +** contents of the Standard cFE File Header of the file identified by +** the given File Descriptor. +** +** \par Assumptions, External Events, and Notes: +** -# The File has already been successfully opened using #OS_OpenCreate and +** the caller has a legitimate File Descriptor. +** +** \param[in] FileDes File Descriptor obtained from a previous call to #OS_OpenCreate +** that is associated with the file whose header is to be read. +** +** \param[in, out] Hdr Pointer to a variable of type #CFE_FS_Header_t that will be +** filled with the contents of the Standard cFE File Header. *Hdr is the contents of the +** Standard cFE File Header for the specified file. +** +** \return Execution status, see \ref CFEReturnCodes +** +** \sa #CFE_FS_WriteHeader +** +******************************************************************************/ +CFE_Status_t CFE_FS_ReadHeader(CFE_FS_Header_t *Hdr, osal_id_t FileDes); + +/*****************************************************************************/ +/** +** \brief Initializes the contents of the Standard cFE File Header +** +** \par Description +** This API will clear the specified #CFE_FS_Header_t variable and +** initialize the description field with the specified value +** +** \param[in] Hdr Pointer to a variable of type #CFE_FS_Header_t that will be +** cleared and initialized +** +** \param[in] *Description Initializes Header's Description +** +** \param[in] SubType Initializes Header's SubType +** +** \sa #CFE_FS_WriteHeader +** +******************************************************************************/ +void CFE_FS_InitHeader(CFE_FS_Header_t *Hdr, const char *Description, uint32 SubType); + +/*****************************************************************************/ +/** +** \brief Write the specified Standard cFE File Header to the specified file +** +** \par Description +** This API will output the specified #CFE_FS_Header_t variable, with some +** fields automatically updated, to the specified file as the Standard cFE +** File Header. This API will automatically populate the following fields +** in the specified #CFE_FS_Header_t: +** +** -# \link #CFE_FS_Header_t::ContentType \c ContentType \endlink - Filled with 0x63464531 ('cFE1') +** -# \link #CFE_FS_Header_t::Length \c Length \endlink - Filled with the sizeof(CFE_FS_Header_t) +** -# \link #CFE_FS_Header_t::SpacecraftID \c SpacecraftID \endlink - Filled with the Spacecraft ID +** -# \link #CFE_FS_Header_t::ProcessorID \c ProcessorID \endlink - Filled with the Processor ID +** -# \link #CFE_FS_Header_t::ApplicationID \c ApplicationID \endlink - Filled with the Application ID +** -# \link #CFE_FS_Header_t::TimeSeconds \c TimeSeconds \endlink - Filled with the Time, in seconds, as obtained +** by #CFE_TIME_GetTime +** -# \link #CFE_FS_Header_t::TimeSubSeconds \c TimeSubSeconds \endlink - Filled with the Time, subseconds, as +** obtained by #CFE_TIME_GetTime +** +** \par Assumptions, External Events, and Notes: +** -# The File has already been successfully opened using #OS_OpenCreate and +** the caller has a legitimate File Descriptor. +** -# The \c SubType field has been filled appropriately by the Application. +** -# The \c Description field has been filled appropriately by the Application. +** +** \param[in] FileDes File Descriptor obtained from a previous call to #OS_OpenCreate +** that is associated with the file whose header is to be read. +** +** \param[in, out] Hdr Pointer to a variable of type #CFE_FS_Header_t that will be +** filled with the contents of the Standard cFE File Header. *Hdr is the contents of the +** Standard cFE File Header for the specified file. +** +** \return Execution status, see \ref CFEReturnCodes +** +** \sa #CFE_FS_ReadHeader +** +******************************************************************************/ +CFE_Status_t CFE_FS_WriteHeader(osal_id_t FileDes, CFE_FS_Header_t *Hdr); + +/*****************************************************************************/ +/** +** \brief Modifies the Time Stamp field in the Standard cFE File Header for the specified file +** +** \par Description +** This API will modify the \link #CFE_FS_Header_t::TimeSeconds timestamp \endlink found +** in the Standard cFE File Header of the specified file. The timestamp will be replaced +** with the time specified by the caller. +** +** \par Assumptions, External Events, and Notes: +** -# The File has already been successfully opened using #OS_OpenCreate and +** the caller has a legitimate File Descriptor. +** -# The \c NewTimestamp field has been filled appropriately by the Application. +** +** \param[in] FileDes File Descriptor obtained from a previous call to #OS_OpenCreate +** that is associated with the file whose header is to be read. +** +** \param[in] NewTimestamp A #CFE_TIME_SysTime_t data structure containing the desired time +** to be put into the file's Standard cFE File Header. +** +** \return Execution status, see \ref CFEReturnCodes +** +******************************************************************************/ +CFE_Status_t CFE_FS_SetTimestamp(osal_id_t FileDes, CFE_TIME_SysTime_t NewTimestamp); +/**@}*/ + +/** @defgroup CFEAPIFSUtil cFE File Utility APIs + * @{ + */ + +/*****************************************************************************/ +/** +** \brief Get the default virtual mount point for a file category +** +** Certain classes of files generally reside in a common directory, mainly +** either the persistent storage (/cf typically) or ram disk (/ram typically). +** +** Ephemeral status files are generally in the ram disk while application +** modules and scripts are generally in the persistent storage. +** +** This returns the expected directory for a given class of files in the form +** of a virtual OSAL mount point string. +** +** \returns String containing the mount point, or NULL if unkown/invalid +*/ +const char *CFE_FS_GetDefaultMountPoint(CFE_FS_FileCategory_t FileCategory); + +/*****************************************************************************/ +/** +** \brief Get the default filename extension for a file category +** +** Certain file types may have an extension that varies from system to system. +** This is primarily an issue for application modules which are ".so" on +** Linux systems, ".dll" on Windows, ".o" on VxWorks, ".obj" on RTEMS, and so on. +** +** This uses a combination of compile-time configuration and hints from the +** build environment to get the default/expected extension for a given file +** category. +** +** \returns String containing the extension, or NULL if unkown/invalid +*/ +const char *CFE_FS_GetDefaultExtension(CFE_FS_FileCategory_t FileCategory); + +/*****************************************************************************/ +/** +** \brief Parse a filename input from an input buffer into a local buffer +** +** \par Description +** This provides a more user friendly way to specify file names, +** using default values for the path and extension, which can +** vary from system to system. +** +** If InputBuffer is null or its length is zero, then DefaultInput +** is used as if it was the content of the input buffer. +** +** If either the pathname or extension is missing from the input, +** it will be added from defaults, with the complete fully-qualified +** filename stored in the output buffer. +** +** \par Assumptions, External Events, and Notes: +** -# The paths and filenames used here are the standard unix style +** filenames separated by "/" (path) and "." (extension) characters. +** -# Input Buffer has a fixed max length. Parsing will not exceed InputBufSize, +** and does not need to be null terminated. However parsing will stop +** at the first null char, when the input is shorter than the maximum. +** +** \param[out] OutputBuffer Buffer to store result. +** \param[in] InputBuffer A input buffer that may contain a file name (e.g. from command). +** \param[in] OutputBufSize Maximum Size of output buffer. +** \param[in] InputBufSize Maximum Size of input buffer. +** \param[in] DefaultInput Default value to use for input if InputBffer is empty +** \param[in] DefaultPath Default value to use for pathname if omitted from input +** \param[in] DefaultExtension Default value to use for extension if omitted from input +** +** \return Execution status, see \ref CFEReturnCodes +** +******************************************************************************/ +int32 CFE_FS_ParseInputFileNameEx(char *OutputBuffer, const char *InputBuffer, size_t OutputBufSize, + size_t InputBufSize, const char *DefaultInput, const char *DefaultPath, + const char *DefaultExtension); + +/*****************************************************************************/ +/** +** \brief Parse a filename string from the user into a local buffer +** +** \par Description +** Simplified API for CFE_FS_ParseInputFileNameEx() where input is +** always known to be a non-empty, null terminated string and the fixed-length +** input buffer not needed. For instance this may be used where +** the input is a fixed string from cfe_platform_cfg.h or similar. +** +** \par Assumptions, External Events, and Notes: +** The parameters are organized such that this is basically like strncpy() with an +** extra argument, and existing file name accesses which use a direct copy can +** easily change to use this instead. +** +** \sa CFE_FS_ParseInputFileNameEx() +** +** \param[out] OutputBuffer Buffer to store result. +** \param[in] InputName A null terminated input string +** \param[in] OutputBufSize Maximum Size of output buffer. +** \param[in] FileCategory The generalized category of file (implies default path/extension) +** +** \return Execution status, see \ref CFEReturnCodes +** +**--------------------------------------------------------------------------------------- +*/ +int32 CFE_FS_ParseInputFileName(char *OutputBuffer, const char *InputName, size_t OutputBufSize, + CFE_FS_FileCategory_t FileCategory); + +/*****************************************************************************/ +/** +** \brief Extracts the filename from a unix style path and filename string. +** +** \par Description +** This API will take the original unix path/filename combination and +** extract the base filename. Example: Given the path/filename : "/cf/apps/myapp.o.gz" +** this function will return the filename: "myapp.o.gz". +** +** \par Assumptions, External Events, and Notes: +** -# The paths and filenames used here are the standard unix style +** filenames separated by "/" characters. +** -# The extracted filename (including terminator) is no longer than #OS_MAX_PATH_LEN +** +** \param[in] OriginalPath The original path. +** \param[out] FileNameOnly The filename that is extracted from the path. +** +** \return Execution status, see \ref CFEReturnCodes +** +******************************************************************************/ +CFE_Status_t CFE_FS_ExtractFilenameFromPath(const char *OriginalPath, char *FileNameOnly); + +/*****************************************************************************/ +/** +** \brief Register a background file dump request +** +** \par Description +** Puts the previously-initialized metadata into the pending request queue +** +** \par Assumptions, External Events, and Notes: +** Metadata structure should be stored in a static memory area (not on heap) as it +** must persist and be accessible by the file writer task throughout the asynchronous +** job operation. +** +** \param[inout] Meta The background file write persistent state object +** +** \return Execution status, see \ref CFEReturnCodes +** +******************************************************************************/ +int32 CFE_FS_BackgroundFileDumpRequest(CFE_FS_FileWriteMetaData_t *Meta); + +/*****************************************************************************/ +/** +** \brief Query if a background file write request is currently pending +** +** \par Description +** This returns "true" while the request is on the background work queue +** This returns "false" once the request is complete and removed from the queue. +** +** \par Assumptions, External Events, and Notes: +** None +** +** \param[inout] Meta The background file write persistent state object +** +** \return true if request is already pending, false if not +** +******************************************************************************/ +bool CFE_FS_BackgroundFileDumpIsPending(const CFE_FS_FileWriteMetaData_t *Meta); + +/*****************************************************************************/ +/** +** \brief Execute the background file write job(s) +** +** \par Description +** Runs the state machine associated with background file write requests +** +** \par Assumptions, External Events, and Notes: +** This should only be invoked as a background job from the ES background task, +** it should not be invoked directly. +** +** \param[in] ElapsedTime The amount of time passed since last invocation (ms) +** \param[in] Arg Not used/ignored +** +** \return true if jobs are pending, false if idle +** +******************************************************************************/ +bool CFE_FS_RunBackgroundFileDump(uint32 ElapsedTime, void *Arg); + +/**@}*/ + +#endif /* CFE_FS_H */ diff --git a/modules/core_api/fsw/inc/cfe_fs_api_typedefs.h b/modules/core_api/fsw/inc/cfe_fs_api_typedefs.h new file mode 100644 index 000000000..0e7a80594 --- /dev/null +++ b/modules/core_api/fsw/inc/cfe_fs_api_typedefs.h @@ -0,0 +1,121 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/** + * @file + * + * Purpose: cFE File Services (FS) library API header file + * + * Author: S.Walling/Microtel + * + */ + +#ifndef CFE_FS_API_TYPEDEFS_H +#define CFE_FS_API_TYPEDEFS_H + +/* +** Required header files... +*/ +#include "common_types.h" +#include "osconfig.h" +#include "cfe_fs_extern_typedefs.h" + +/** + * \brief Generalized file types/categories known to FS + * + * This defines different categories of files, where they + * may reside in different default locations of the virtualized file system. + * + * This is different from, and should not be confused with, the "SubType" + * field in the FS header. This value is only used at runtime for FS APIs + * and should not actually appear in any output file or message. + */ +typedef enum +{ + CFE_FS_FileCategory_UNKNOWN, /**< Placeholder, unknown file category */ + CFE_FS_FileCategory_DYNAMIC_MODULE, /**< Dynamically loadable apps/libraries (e.g. .so, .o, .dll, etc) */ + CFE_FS_FileCategory_BINARY_DATA_DUMP, /**< Binary log file generated by various data dump commands */ + CFE_FS_FileCategory_TEXT_LOG, /**< Text-based log file generated by various commands */ + CFE_FS_FileCategory_SCRIPT, /**< Text-based Script files (e.g. ES startup script) */ + CFE_FS_FileCategory_TEMP, /**< Temporary/Ephemeral files */ + CFE_FS_FileCategory_MAX /**< Placeholder, keep last */ +} CFE_FS_FileCategory_t; + +/* + * Because FS is a library not an app, it does not have its own context or + * event IDs. The file writer runs in the context of the ES background task + * on behalf of whatever App requested the file write. + * + * This is a list of abstract events associated with background file write jobs. + * An app requesting the file write must supply a callback function to translate + * these into its own event IDs for feedback (i.e. file complete, error conditions, etc). + */ +typedef enum +{ + CFE_FS_FileWriteEvent_UNDEFINED, /* placeholder, no-op, keep as 0 */ + + CFE_FS_FileWriteEvent_COMPLETE, /**< File is completed successfully */ + CFE_FS_FileWriteEvent_CREATE_ERROR, /**< Unable to create/open file */ + CFE_FS_FileWriteEvent_HEADER_WRITE_ERROR, /**< Unable to write FS header */ + CFE_FS_FileWriteEvent_RECORD_WRITE_ERROR, /**< Unable to write data record */ + + CFE_FS_FileWriteEvent_MAX /* placeholder, no-op, keep last */ + +} CFE_FS_FileWriteEvent_t; + +/** + * Data Getter routine provided by requester + * + * Outputs a data block. Should return true if the file is complete (last record/EOF), otherwise return false. + */ +typedef bool (*CFE_FS_FileWriteGetData_t)(void *Meta, uint32 RecordNum, void **Buffer, size_t *BufSize); + +/** + * Event generator routine provided by requester + * + * Invoked from certain points in the file write process. Implementation may invoke CFE_EVS_SendEvent() appropriately + * to inform of progress. + */ +typedef void (*CFE_FS_FileWriteOnEvent_t)(void *Meta, CFE_FS_FileWriteEvent_t Event, int32 Status, uint32 RecordNum, + size_t BlockSize, size_t Position); + +/** + * \brief External Metadata/State object associated with background file writes + * + * Applications intending to schedule background file write jobs should instantiate + * this object in static/global data memory. This keeps track of the state of the + * file write request(s). + */ +typedef struct CFE_FS_FileWriteMetaData +{ + volatile bool IsPending; /**< Whether request is pending (volatile as it may be checked outside lock) */ + + char FileName[OS_MAX_PATH_LEN]; /**< Name of file to write */ + + /* Data for FS header */ + uint32 FileSubType; /**< Type of file to write (for FS header) */ + char Description[CFE_FS_HDR_DESC_MAX_LEN]; /**< Description of file (for FS header) */ + + CFE_FS_FileWriteGetData_t GetData; /**< Application callback to get a data record */ + CFE_FS_FileWriteOnEvent_t OnEvent; /**< Application callback for abstract event processing */ + +} CFE_FS_FileWriteMetaData_t; + +#endif /* CFE_FS_API_TYPEDEFS_H */ diff --git a/modules/core_api/fsw/inc/cfe_fs_core_internal.h b/modules/core_api/fsw/inc/cfe_fs_core_internal.h new file mode 100644 index 000000000..ee1f8768d --- /dev/null +++ b/modules/core_api/fsw/inc/cfe_fs_core_internal.h @@ -0,0 +1,60 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/** + * @file + * + * Purpose: cFE File Services (FS) library API header file + * + * Author: S.Walling/Microtel + * + */ + +#ifndef CFE_FS_CORE_INTERNAL_H +#define CFE_FS_CORE_INTERNAL_H + +#include "common_types.h" + +/* + * The internal APIs prototyped within this block are only intended to be invoked from + * other CFE core apps. They still need to be prototyped in the shared header such that + * they can be called from other core modules, but applications should not call these. + */ + +/** @defgroup CFEAPIFSCoreInternal cFE Internal File Service APIs, internal to CFE core + * @{ + */ + +/*****************************************************************************/ +/** +** \brief Initializes the cFE core module API Library +** +** \par Description +** Initializes the cFE core module API Library +** +** \par Assumptions, External Events, and Notes: +** -# This function MUST be called before any module API's are called. +** +******************************************************************************/ +extern int32 CFE_FS_EarlyInit(void); + +/**@}*/ + +#endif /* CFE_FS_CORE_INTERNAL_H */ diff --git a/modules/core_api/fsw/inc/cfe_fs_extern_typedefs.h b/modules/core_api/fsw/inc/cfe_fs_extern_typedefs.h new file mode 100644 index 000000000..d1780b544 --- /dev/null +++ b/modules/core_api/fsw/inc/cfe_fs_extern_typedefs.h @@ -0,0 +1,230 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/** + * @file + * + * Declarations and prototypes for cfe_fs_extern_typedefs module + */ + +#ifndef CFE_FS_EXTERN_TYPEDEFS_H +#define CFE_FS_EXTERN_TYPEDEFS_H + +/* This header may be generated from an EDS file, + * tools are available and the feature is enabled */ +#ifdef CFE_EDS_ENABLED_BUILD + +/* Use the EDS generated version of these types */ +#include "cfe_fs_eds_typedefs.h" + +#else +/* Use the local definitions of these types */ + +#include "common_types.h" + +/******************* Macro Definitions ***********************/ + +/* + * NOTE: the value of CFE_FS_HDR_DESC_MAX_LEN, if modified, should + * be constrained to multiples of 4, as it is used within a structure that + * also contains uint32 types. This ensures that the entire structure + * remains 32-bit aligned without the need for implicit padding bytes. + */ + +#define CFE_FS_HDR_DESC_MAX_LEN 32 /**< \brief Max length of description field in a standard cFE File Header */ + +#define CFE_FS_FILE_CONTENT_ID 0x63464531 /**< \brief Magic Number for cFE compliant files (= 'cFE1') */ + +/** + * @brief Label definitions associated with CFE_FS_SubType_Enum_t + */ +enum CFE_FS_SubType +{ + + /** + * @brief Executive Services Exception/Reset Log Type + * + * Executive Services Exception/Reset Log File which is generated in response to a + * \link #CFE_ES_WRITE_ER_LOG_CC \ES_WRITEERLOG2FILE \endlink + * command. + * + */ + CFE_FS_SubType_ES_ERLOG = 1, + + /** + * @brief Executive Services System Log Type + * + * Executive Services System Log File which is generated in response to a + * \link #CFE_ES_WRITE_SYSLOG_CC \ES_WRITESYSLOG2FILE \endlink + * command. + * + */ + CFE_FS_SubType_ES_SYSLOG = 2, + + /** + * @brief Executive Services Information on All Applications File + * + * Executive Services Information on All Applications File which is generated in response to a + * \link #CFE_ES_QUERY_ALL_CC \ES_WRITEAPPINFO2FILE \endlink + * command. + * + */ + CFE_FS_SubType_ES_QUERYALL = 3, + + /** + * @brief Executive Services Performance Data File + * + * Executive Services Performance Analyzer Data File which is generated in response to a + * \link #CFE_ES_STOP_PERF_DATA_CC \ES_STOPLADATA \endlink + * command. + * + */ + CFE_FS_SubType_ES_PERFDATA = 4, + + /** + * @brief Executive Services Shell Response File + * + * Executive Services Shell Response Data File which is generated in response to a + * shell command. + * + */ + CFE_FS_SubType_ES_SHELL = 5, + + /** + * @brief Executive Services Critical Data Store Registry Dump File + * + * Executive Services Critical Data Store Registry Dump File which is generated in response to a + * \link #CFE_ES_DUMP_CDS_REGISTRY_CC \ES_DUMPCDSREG \endlink + * command. + * + */ + CFE_FS_SubType_ES_CDS_REG = 6, + + /** + * @brief Table Services Registry Dump File + * + * Table Services Registry Dump File which is generated in response to a + * \link #CFE_TBL_DUMP_REGISTRY_CC \TBL_WRITEREG2FILE \endlink + * command. + * + */ + CFE_FS_SubType_TBL_REG = 9, + + /** + * @brief Table Services Table Image File + * + * Table Services Table Image File which is generated either on the ground or in response to a + * \link #CFE_TBL_DUMP_CC \TBL_DUMP \endlink command. + * + */ + CFE_FS_SubType_TBL_IMG = 8, + + /** + * @brief Event Services Application Data Dump File + * + * Event Services Application Data Dump File which is generated in response to a + * \link #CFE_EVS_WRITE_APP_DATA_FILE_CC \EVS_WRITEAPPDATA2FILE \endlink + * command. + * + */ + CFE_FS_SubType_EVS_APPDATA = 15, + + /** + * @brief Event Services Local Event Log Dump File + * + * Event Services Local Event Log Dump File which is generated in response to a + * \link #CFE_EVS_WRITE_LOG_DATA_FILE_CC \EVS_WRITELOG2FILE \endlink + * command. + * + */ + CFE_FS_SubType_EVS_EVENTLOG = 16, + + /** + * @brief Software Bus Pipe Data Dump File + * + * Software Bus Pipe Data Dump File which is generated in response to a + * \link #CFE_SB_WRITE_PIPE_INFO_CC \SB_WRITEPIPE2FILE \endlink + * command. + * + */ + CFE_FS_SubType_SB_PIPEDATA = 20, + + /** + * @brief Software Bus Message Routing Data Dump File + * + * Software Bus Message Routing Data Dump File which is generated in response to a + * \link #CFE_SB_WRITE_ROUTING_INFO_CC \SB_WRITEROUTING2FILE \endlink + * command. + * + */ + CFE_FS_SubType_SB_ROUTEDATA = 21, + + /** + * @brief Software Bus Message Mapping Data Dump File + * + * Software Bus Message Mapping Data Dump File which is generated in response to a + * \link #CFE_SB_WRITE_MAP_INFO_CC \SB_WRITEMAP2FILE \endlink + * command. + * + */ + CFE_FS_SubType_SB_MAPDATA = 22, + + /** + * @brief Executive Services Query All Tasks Data File + * + * Executive Services Query All Tasks Data File which is generated in response to a + * \link #CFE_ES_QUERY_ALL_TASKS_CC \ES_WRITETASKINFO2FILE \endlink + * command. + * + */ + CFE_FS_SubType_ES_QUERYALLTASKS = 23 +}; + +/** + * @brief Content descriptor for File Headers + * + * @sa enum CFE_FS_SubType + */ +typedef uint32 CFE_FS_SubType_Enum_t; + +/** +** \brief Standard cFE File header structure definition +*/ +typedef struct CFE_FS_Header +{ + uint32 ContentType; /**< \brief Identifies the content type (='cFE1'=0x63464531)*/ + uint32 SubType; /**< \brief Type of \c ContentType, if necessary */ + /**< Standard SubType definitions can be found + \link #CFE_FS_SubType_ES_ERLOG here \endlink */ + uint32 Length; /**< \brief Length of primary header */ + uint32 SpacecraftID; /**< \brief Spacecraft that generated the file */ + uint32 ProcessorID; /**< \brief Processor that generated the file */ + uint32 ApplicationID; /**< \brief Application that generated the file */ + + uint32 TimeSeconds; /**< \brief File creation timestamp (seconds) */ + uint32 TimeSubSeconds; /**< \brief File creation timestamp (sub-seconds) */ + + char Description[CFE_FS_HDR_DESC_MAX_LEN]; /**< \brief File description */ + +} CFE_FS_Header_t; + +#endif /* CFE_EDS_ENABLED_BUILD */ + +#endif /* CFE_FS_EXTERN_TYPEDEFS_H */ diff --git a/modules/core_private/fsw/inc/cfe_evs_log_typedef.h b/modules/core_private/fsw/inc/cfe_evs_log_typedef.h new file mode 100644 index 000000000..66da533b0 --- /dev/null +++ b/modules/core_private/fsw/inc/cfe_evs_log_typedef.h @@ -0,0 +1,51 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/** + * @file + * + * Definition of the CFE_EVS_Log structure type. + * This was moved into its own header file since it is referenced by multiple CFE core apps. + */ + +#ifndef CFE_EVS_LOG_TYPEDEF_H +#define CFE_EVS_LOG_TYPEDEF_H + +#include "common_types.h" +#include "cfe_platform_cfg.h" + +#include "cfe_evs_msg.h" /* Required for CFE_EVS_LongEventTlm_t definition */ + +/* +** \brief EVS Log type definition. This is declared here so ES can include it +** in the reset area structure +*/ +typedef struct +{ + uint16 Next; /**< \brief Index of the next entry in the local event log */ + uint16 LogCount; /**< \brief Local Event Kog counter */ + uint8 LogFullFlag; /**< \brief Local Event Log full flag */ + uint8 LogMode; /**< \brief Local Event Logging mode (overwrite/discard) */ + uint16 LogOverflowCounter; /**< \brief Local Event Log overflow counter */ + CFE_EVS_LongEventTlm_t LogEntry[CFE_PLATFORM_EVS_LOG_MAX]; /**< \brief The actual Local Event Log entry */ + +} CFE_EVS_Log_t; + +#endif /* CFE_EVS_LOG_TYPEDEF_H */ diff --git a/modules/evs/CMakeLists.txt b/modules/evs/CMakeLists.txt new file mode 100644 index 000000000..a406d1651 --- /dev/null +++ b/modules/evs/CMakeLists.txt @@ -0,0 +1,33 @@ +################################################################## +# +# cFE Event Services (EVS) module CMake build recipe +# +################################################################## + +project(CFE_EVS C) + +# Event services source files +set(evs_SOURCES + fsw/src/cfe_evs.c + fsw/src/cfe_evs_log.c + fsw/src/cfe_evs_task.c + fsw/src/cfe_evs_utils.c + fsw/src/cfe_evs.c + fsw/src/cfe_evs_log.c + fsw/src/cfe_evs_task.c + fsw/src/cfe_evs_utils.c +) +add_library(evs STATIC ${evs_SOURCES}) + +target_include_directories(evs PUBLIC fsw/inc) +target_link_libraries(evs PRIVATE core_private) + +# Add unit test coverage subdirectory +if(ENABLE_UNIT_TESTS) + add_subdirectory(ut-coverage) +endif(ENABLE_UNIT_TESTS) + +cfs_app_check_intf(${DEP} + cfe_evs_msg.h + cfe_evs_events.h +) diff --git a/modules/evs/fsw/inc/cfe_evs_events.h b/modules/evs/fsw/inc/cfe_evs_events.h new file mode 100644 index 000000000..8f1f8db1e --- /dev/null +++ b/modules/evs/fsw/inc/cfe_evs_events.h @@ -0,0 +1,642 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/** + * @file + * + * Purpose: + * cFE Event Services (EVS) Event IDs + * + * Design Notes: + * + * References: + * Flight Software Branch C Coding Standard Version 1.0a + * + */ + +#ifndef CFE_EVS_EVENTS_H +#define CFE_EVS_EVENTS_H + +/* ************************** +** ****** Maximum EID. ****** +** ************************** +** The EID's below may not necessarily be in order, so it can be difficult to +** determine what the next EID is to use. When you add EID's, start with MAX_EID + 1 +** and when you're done adding, set this to the highest EID you used. It may +** be worthwhile to, on occasion, re-number the EID's to put them back in order. +*/ +#define CFE_EVS_MAX_EID 43 + +/* Event Service event ID's */ + +/** \brief 'No-op command' +** \event 'No-op command' +** +** \par Type: INFORMATION +** +** \par Cause: +** +** This event message is always automatically issued in response +** to a cFE Event Services \link #CFE_EVS_NOOP_CC NO-OP command \endlink +**/ +#define CFE_EVS_NOOP_EID 0 /* Noop event identifier */ + +/** \brief 'cFE EVS Initialized' +** \event 'cFE EVS Initialized' +** +** \par Type: INFORMATION +** +** \par Cause: +** +** This event message is always automatically issued when the Event Services +** Task completes its Initialization. +**/ +#define CFE_EVS_STARTUP_EID 1 + +/** \brief 'Write Log File Command Error: OS_write = 0x\%08X, filename = \%s' +** \event 'Write Log File Command Error: OS_write = 0x\%08X, filename = \%s' +** +** \par Type: ERROR +** +** \par Cause: +** +** This event message is generated when a filesystem error occurred while writing the contents of the +** event message log to a file. +** +** The message text identifies the event log filename and specifies the return value, in hex, +** from the system function call. The expected return value is the number of bytes written, +** which in this case should be equal to the size of a #CFE_EVS_LongEventTlm_t structure. Error +** codes are negative. +**/ +#define CFE_EVS_ERR_WRLOGFILE_EID 2 + +/** \brief 'Write Log File Command Error: OS_OpenCreate = 0x\%08X, filename = \%s' +** \event 'Write Log File Command Error: OS_OpenCreate = 0x\%08X, filename = \%s' +** +** \par Type: ERROR +** +** \par Cause: +** +** This event message is generated when a filesystem error occurred when attempting to create the file +** that is to hold the event message log. +** +** The message text identifies the event log filename and specifies the return value, in hex, +** from the system function call. The expected return value is a file handle, which in this case +** should be a relatively small positive number. Error codes are negative. +**/ +#define CFE_EVS_ERR_CRLOGFILE_EID 3 + +/** \brief 'Invalid command packet, Message ID = 0x\%08X' +** \event 'Invalid command packet, Message ID = 0x\%08X' +** +** \par Type: ERROR +** +** \par Cause: +** +** This event message is generated when a message has arrived on +** the cFE Event Services Application's Message Pipe that has a +** Message ID that is neither #CFE_EVS_CMD_MID or #CFE_EVS_SEND_HK_MID. +** Most likely, the cFE Software Bus routing table has become corrupt +** and is sending messages targeted for other Applications to the cFE +** Event Services Application. +** +** The \c ID field in the event message identifies +** the message ID (in hex) that was found in the message. +**/ +#define CFE_EVS_ERR_MSGID_EID 5 + +/** \brief '\%s Event ID \%d not registered for filtering: CC = \%lu' +** \event '\%s Event ID \%d not registered for filtering: CC = \%lu' +** +** \par Type: ERROR +** +** \par Cause: +** +** This event message is generated when the specified command identifies an Application and Event ID combination +** that is not found in the Events Registry. +** +** The \c \%s string contains the command specified Application Name the \c Event \c ID field +** identifies the command specified EventID (in decimal) that was not found in the Events Registry. +** The \c CC field specifies the Command Code whose processing generated the event message. It can +** be equal to either #CFE_EVS_SET_FILTER_CC, #CFE_EVS_RESET_FILTER_CC, or #CFE_EVS_DELETE_EVENT_FILTER_CC. +**/ +#define CFE_EVS_ERR_EVTIDNOREGS_EID 6 + +/** \brief '\%s not registered with EVS: CC = \%lu' +** \event '\%s not registered with EVS: CC = \%lu' +** +** \par Type: ERROR +** +** \par Cause: +** +** This event message is generated when the specified command identifies an Application that has not been +** registered with the cFE Event Services. +** +** The \c CC field contains the Command Code whose processing resulted in the generation of the event message. +** Possible values are #CFE_EVS_SET_FILTER_CC, #CFE_EVS_ENABLE_APP_EVENT_TYPE_CC, #CFE_EVS_DISABLE_APP_EVENT_TYPE_CC, +** #CFE_EVS_ENABLE_APP_EVENTS_CC, #CFE_EVS_DISABLE_APP_EVENTS_CC, #CFE_EVS_RESET_APP_COUNTER_CC, +*#CFE_EVS_RESET_FILTER_CC, +** #CFE_EVS_RESET_ALL_FILTERS_CC, #CFE_EVS_ADD_EVENT_FILTER_CC, or #CFE_EVS_DELETE_EVENT_FILTER_CC. +**/ +#define CFE_EVS_ERR_APPNOREGS_EID 7 + +/** \brief 'Illegal application ID \%d retrieved for \%s: CC = \%lu' +** \event 'Illegal application ID \%d retrieved for \%s: CC = \%lu' +** +** \par Type: ERROR +** +** \par Cause: +** +** This event message is generated when the specified command identifies an Application whose name is +** found in the Events Registry but does not appear to be properly registered with the cFE Executive Services. +** +** The \c CC field contains the Command Code whose processing resulted in the generation of the event message. +** Possible values are #CFE_EVS_SET_FILTER_CC, #CFE_EVS_ENABLE_APP_EVENT_TYPE_CC, #CFE_EVS_DISABLE_APP_EVENT_TYPE_CC, +** #CFE_EVS_ENABLE_APP_EVENTS_CC, #CFE_EVS_DISABLE_APP_EVENTS_CC, #CFE_EVS_RESET_APP_COUNTER_CC, +*#CFE_EVS_RESET_FILTER_CC, +** #CFE_EVS_RESET_ALL_FILTERS_CC, #CFE_EVS_ADD_EVENT_FILTER_CC, or #CFE_EVS_DELETE_EVENT_FILTER_CC. +**/ +#define CFE_EVS_ERR_ILLAPPIDRANGE_EID 8 + +/** \brief 'Unable to retrieve application ID for \%s: CC = \%lu' +** \event 'Unable to retrieve application ID for \%s: CC = \%lu' +** +** \par Type: ERROR +** +** \par Cause: +** +** This event message is generated when the specified command contains an Application name that is +** apparently found in the Events Registry but does not appear to be registered with the cFE Executive Services. +** +** The \c CC field contains the Command Code whose processing resulted in the generation of the event message. +** Possible values are #CFE_EVS_SET_FILTER_CC, #CFE_EVS_ENABLE_APP_EVENT_TYPE_CC, #CFE_EVS_DISABLE_APP_EVENT_TYPE_CC, +** #CFE_EVS_ENABLE_APP_EVENTS_CC, #CFE_EVS_DISABLE_APP_EVENTS_CC, #CFE_EVS_RESET_APP_COUNTER_CC, +*#CFE_EVS_RESET_FILTER_CC, +** #CFE_EVS_RESET_ALL_FILTERS_CC, #CFE_EVS_ADD_EVENT_FILTER_CC, or #CFE_EVS_DELETE_EVENT_FILTER_CC. +**/ +#define CFE_EVS_ERR_NOAPPIDFOUND_EID 9 + +/** \brief 'Set Event Format Mode Command: Invalid Event Format Mode = 0x\%02x' +** \event 'Set Event Format Mode Command: Invalid Event Format Mode = 0x\%02x' +** +** \par Type: ERROR +** +** \par Cause: +** +** This event message is generated when a "Set Event Format Mode" command +** message has arrived and the #CFE_EVS_SetLogMode_Payload_t::LogMode field is equal to +** neither #CFE_EVS_MsgFormat_SHORT or #CFE_EVS_MsgFormat_LONG. These are +** the only allowed values for the mode field. +** +** The \c Mode field in the event message identifies +** the Mode value (in hex) that was found in the message. +**/ +#define CFE_EVS_ERR_ILLEGALFMTMOD_EID 10 + +/** \brief 'Add Filter Command: number of registered filters has reached max = \%d' +** \event 'Add Filter Command: number of registered filters has reached max = \%d' +** +** \par Type: ERROR +** +** \par Cause: +** +** This event message is generated upon receipt of an "Add Filter" command +** and the specified Application has already reached the maximum number of +** filters allowed (#CFE_PLATFORM_EVS_MAX_EVENT_FILTERS). +** +** The \c max field in the event message identifies the maximum number of +** event filters allowed per Application. This value should be equal to +** the configuration parameter #CFE_PLATFORM_EVS_MAX_EVENT_FILTERS. +**/ +#define CFE_EVS_ERR_MAXREGSFILTER_EID 11 + +/** \brief 'Write App Data Command Error: OS_write = 0x\%08X, filename = \%s' +** \event 'Write App Data Command Error: OS_write = 0x\%08X, filename = \%s' +** +** \par Type: ERROR +** +** \par Cause: +** +** This event message is generated when a filesystem error occurred while writing the contents of the +** event registry to a file. +** +** The message text identifies the registry filename and specifies the return value, in hex, +** from the system function call. The expected return value is the number of bytes written, +** which in this case should be equal to the size of a CFE_EVS_AppDataFile_t structure. Error +** codes are negative. +**/ +#define CFE_EVS_ERR_WRDATFILE_EID 12 + +/** \brief 'Write App Data Command Error: OS_OpenCreate = 0x\%08X, filename = \%s' +** \event 'Write App Data Command Error: OS_OpenCreate = 0x\%08X, filename = \%s' +** +** \par Type: ERROR +** +** \par Cause: +** +** This event message is generated when a filesystem error occurred when attempting to create the file +** that is to hold the event registry data. +** +** The message text identifies the registry filename and specifies the return value, in hex, +** from the system function call. The expected return value is a file handle, which in this case +** should be a relatively small positive number. Error codes are negative. +**/ +#define CFE_EVS_ERR_CRDATFILE_EID 13 + +/** \brief 'Invalid command code -- ID = 0x\%08x, CC = \%d' +** \event 'Invalid command code -- ID = 0x\%08x, CC = \%d' +** +** \par Type: ERROR +** +** \par Cause: +** +** This event message is generated when a message with the #CFE_EVS_CMD_MID +** message ID has arrived but whose Command Code is not one of the specified +** accepted command codes specified. This problem is most likely to occur when: +** -# A Message ID meant for another Application became corrupted and was +** set equal to #CFE_EVS_CMD_MID. +** -# The Command Code field in the Message became corrupted. +** -# The command database at the ground station has been corrupted. +** +** The \c ID field in the event message specifies the Message ID (in hex) and the +** \c CC field specifies the Command Code (in decimal) found in the message. +**/ +#define CFE_EVS_ERR_CC_EID 15 + +/** \brief 'Reset Counters Command Received' +** \event 'Reset Counters Command Received' +** +** \par Type: DEBUG +** +** \par Cause: +** +** This event message is always automatically issued in response +** to a cFE Event Services Reset Counters command +**/ +#define CFE_EVS_RSTCNT_EID 16 + +/** \brief 'Set Filter Mask Command Received with AppName=\%s, EventID=0x\%08x, Mask=0x\%04x' +** \event 'Set Filter Mask Command Received with AppName=\%s, EventID=0x\%08x, Mask=0x\%04x' +** +** \par Type: DEBUG +** +** \par Cause: +** +** This event message is issued upon successful processing of a Set Filter Mask command. +** +** The \c AppName field identifies the Application whose Filter Mask has been changed. +** The \c EventID field identifies the Event whose Filter Mask has been changed. +** The \c Mask field identifies the new Mask value associated with the specified event. +**/ +#define CFE_EVS_SETFILTERMSK_EID 17 + +/** \brief 'Enable Ports Command Received with Port Bit Mask = 0x\%02x' +** \event 'Enable Ports Command Received with Port Bit Mask = 0x\%02x' +** +** \par Type: DEBUG +** +** \par Cause: +** +** This event message is issued upon successful processing of the "Enable Ports" command. +** +** The \c Mask field identifies the ports that are enabled. +** Mask bits are defined by #CFE_EVS_PORT1_BIT, #CFE_EVS_PORT2_BIT, #CFE_EVS_PORT3_BIT and #CFE_EVS_PORT4_BIT. +**/ +#define CFE_EVS_ENAPORT_EID 18 + +/** \brief 'Disable Ports Command Received with Port Bit Mask = 0x\%02x' +** \event 'Disable Ports Command Received with Port Bit Mask = 0x\%02x' +** +** \par Type: DEBUG +** +** \par Cause: +** +** This event message is issued upon successful processing of the "Disable Ports" command. +** +** The \c Mask field identifies (in hex) the ports are to be disabled. +** Mask bits are defined by #CFE_EVS_PORT1_BIT, #CFE_EVS_PORT2_BIT, #CFE_EVS_PORT3_BIT and #CFE_EVS_PORT4_BIT. +**/ +#define CFE_EVS_DISPORT_EID 19 + +/** \brief 'Enable Event Type Command Received with Event Type Bit Mask = 0x\%02x' +** \event 'Enable Event Type Command Received with Event Type Bit Mask = 0x\%02x' +** +** \par Type: DEBUG +** +** \par Cause: +** +** This event message is issued upon successful processing of the "Enable Event Type" command. +** +** The \c Mask field identifies the Event Types that are enabled. +** Mask bits are defined by #CFE_EVS_DEBUG_BIT, #CFE_EVS_INFORMATION_BIT, +** #CFE_EVS_ERROR_BIT and #CFE_EVS_CRITICAL_BIT. +**/ +#define CFE_EVS_ENAEVTTYPE_EID 20 + +/** \brief 'Disable Event Type Command Received with Event Type Bit Mask = 0x\%02x' +** \event 'Disable Event Type Command Received with Event Type Bit Mask = 0x\%02x' +** +** \par Type: DEBUG +** +** \par Cause: +** +** This event message is issued upon successful processing of the "Disable Event Type" command. +** +** The \c Mask field identifies the Event Types that are disabled. +** Mask bits are defined by #CFE_EVS_DEBUG_BIT, #CFE_EVS_INFORMATION_BIT, +** #CFE_EVS_ERROR_BIT and #CFE_EVS_CRITICAL_BIT. +**/ +#define CFE_EVS_DISEVTTYPE_EID 21 + +/** \brief 'Set Event Format Mode Command Received with Mode = 0x\%02x' +** \event 'Set Event Format Mode Command Received with Mode = 0x\%02x' +** +** \par Type: DEBUG +** +** \par Cause: +** +** This event message is generated upon successful completion of the "Set Event Format Mode" command. +** +** The \c Mode field contains the newly chosen Event Format Mode (specified in hex). Acceptable values +** for this parameter are: #CFE_EVS_MsgFormat_SHORT or #CFE_EVS_MsgFormat_LONG +**/ +#define CFE_EVS_SETEVTFMTMOD_EID 22 + +/** \brief 'Enable App Event Type Command Received with AppName = \%s, EventType Bit Mask = 0x\%02x' +** \event 'Enable App Event Type Command Received with AppName = \%s, EventType Bit Mask = 0x\%02x' +** +** \par Type: DEBUG +** +** \par Cause: +** +** This event message is generated upon successful completion of the "Enable Application Event Types" command. +** +** The \c AppName field identifies the Application whose Event Type Enable status has changed and the +** \c Mask field specifies (in hex) the Event Types that have been enabled. +** Mask bits are defined by #CFE_EVS_DEBUG_BIT, #CFE_EVS_INFORMATION_BIT, +** #CFE_EVS_ERROR_BIT and #CFE_EVS_CRITICAL_BIT. +**/ +#define CFE_EVS_ENAAPPEVTTYPE_EID 23 + +/** \brief 'Disable App Event Type Command Received with AppName = \%s, EventType Bit Mask = 0x\%02x' +** \event 'Disable App Event Type Command Received with AppName = \%s, EventType Bit Mask = 0x\%02x' +** +** \par Type: DEBUG +** +** \par Cause: +** +** This event message is generated upon successful completion of the "Disable Application Event Types" command. +** +** The \c AppName field identifies the Application whose Event Type Disable status has changed and the +** \c Mask field specifies (in hex) the Event Types that have been disabled. +** Mask bits are defined by #CFE_EVS_DEBUG_BIT, #CFE_EVS_INFORMATION_BIT, +** #CFE_EVS_ERROR_BIT and #CFE_EVS_CRITICAL_BIT. +**/ +#define CFE_EVS_DISAPPENTTYPE_EID 24 + +/** \brief 'Enable App Events Command Received with AppName = \%s' +** \event 'Enable App Events Command Received with AppName = \%s' +** +** \par Type: DEBUG +** +** \par Cause: +** +** This event message is generated upon successful completion of the "Enable Application Events" command. +** +** The \c AppName field identifies the Application whose Events have been Enabled. +**/ +#define CFE_EVS_ENAAPPEVT_EID 25 + +/** \brief 'Disable App Events Command Received with AppName = \%s' +** \event 'Disable App Events Command Received with AppName = \%s' +** +** \par Type: DEBUG +** +** \par Cause: +** +** This event message is generated upon successful completion of the "Disable Application Events" command. +** +** The \c AppName field identifies the Application whose Events have been Disabled. +**/ +#define CFE_EVS_DISAPPEVT_EID 26 + +/** \brief 'Reset Event Counter Command Received with AppName = \%s' +** \event 'Reset Event Counter Command Received with AppName = \%s' +** +** \par Type: DEBUG +** +** \par Cause: +** +** This event message is generated upon successful completion of the "Reset Application Event Counter" command. +** +** The \c AppName field identifies the Application whose Event Counter has been reset. +**/ +#define CFE_EVS_RSTEVTCNT_EID 27 + +/** \brief 'Reset Filter Command Received with AppName = \%s, EventID = 0x\%08x' +** \event 'Reset Filter Command Received with AppName = \%s, EventID = 0x\%08x' +** +** \par Type: DEBUG +** +** \par Cause: +** +** This event message is generated upon successful completion of the "Reset Application Event Message Filter" command. +** +** The \c AppName field identifies the Application whose Event Message Filter has been reset and +** the \c EventID field identifies the specific event message whose filter has been reset. +**/ +#define CFE_EVS_RSTFILTER_EID 28 + +/** \brief 'Reset All Filters Command Received with AppName = \%s' +** \event 'Reset All Filters Command Received with AppName = \%s' +** +** \par Type: DEBUG +** +** \par Cause: +** +** This event message is generated upon successful completion of the "Reset Application Event Message Filters" command. +** +** The \c AppName field identifies the Application whose entire set of Event Filters has been reset. +**/ +#define CFE_EVS_RSTALLFILTER_EID 29 + +/** \brief 'Add Filter Command Received with AppName = \%s, EventID = 0x\%08x, Mask = 0x\%04x' +** \event 'Add Filter Command Received with AppName = \%s, EventID = 0x\%08x, Mask = 0x\%04x' +** +** \par Type: DEBUG +** +** \par Cause: +** +** This event message is generated upon successful completion of the "Add Filter" command. +** +** The \c AppName field identifies the Application who is getting the new filter, the \c EventID field +** identifies the Event Identifier, in hex, that is getting the filter, and the \c Mask field specifies, in hex, +** what the binary filter mask has been set to. +**/ +#define CFE_EVS_ADDFILTER_EID 30 + +/** \brief 'Delete Filter Command Received with AppName = \%s, EventID = 0x\%08x' +** \event 'Delete Filter Command Received with AppName = \%s, EventID = 0x\%08x' +** +** \par Type: DEBUG +** +** \par Cause: +** +** This event message is generated upon successful completion of the "Delete Filter" command. +** +** The \c AppName field identifies the Application who is getting the filter removed, the \c EventID field +** identifies the Event Identifier, in hex, whose filter is being deleted. +**/ +#define CFE_EVS_DELFILTER_EID 31 + +/** \brief 'Write App Data Command: \%d application data entries written to \%s' +** \event 'Write App Data Command: \%d application data entries written to \%s' +** +** \par Type: DEBUG +** +** \par Cause: +** +** This event message is generated upon successful completion of the +** \link #CFE_EVS_WRITE_APP_DATA_FILE_CC "Write Event Services Application Information to File" \endlink command. +** +** The message text identifies the event log filename and specifies the number, in decimal, +** of events written to the file. +**/ +#define CFE_EVS_WRDAT_EID 32 + +/** \brief 'Write Log File Command: \%d event log entries written to \%s' +** \event 'Write Log File Command: \%d event log entries written to \%s' +** +** \par Type: DEBUG +** +** \par Cause: +** +** This event message is generated upon successful completion of the +** \link #CFE_EVS_WRITE_LOG_DATA_FILE_CC "Write Event Log to File" \endlink command. +** +** The message text identifies the event log filename and specifies the number, in decimal, +** of events written to the file. +**/ +#define CFE_EVS_WRLOG_EID 33 + +/** \brief 'Add Filter Command:AppName = \%s, EventID = 0x\%08x is already registered for filtering' +** \event 'Add Filter Command:AppName = \%s, EventID = 0x\%08x is already registered for filtering' +** +** \par Type: ERROR +** +** \par Cause: +** +** This event message is generated when an "Add Filter" command was received specifying an Event ID that has already +** had a filter added. +** +** The \c AppName field identifies the Application whose filter was to be added and the \c EventID field identifies, +** in hex, the Event ID that the command was trying to add a filter for. +**/ +#define CFE_EVS_EVT_FILTERED_EID 37 + +/** \brief 'Set Log Mode Command Error: Log Mode = \%d' +** \event 'Set Log Mode Command Error: Log Mode = \%d' +** +** \par Type: DEBUG +** +** \par Cause: +** +** This event message is generated when a "Set Log Mode" command is completed successfully. +** +** The event text identifies the Log Mode command argument. Valid Log Mode command +** arguments are: #CFE_EVS_LOG_OVERWRITE or #CFE_EVS_LOG_DISCARD. +**/ +#define CFE_EVS_LOGMODE_EID 38 + +/** \brief 'Set Log Mode Command Error: Log Mode = \%d' +** \event 'Set Log Mode Command Error: Log Mode = \%d +** +** \par Type: ERROR +** +** \par Cause: +** +** This event message is generated when a "Set Log Mode" command is received that specifies +** an invalid Log Mode command argument. +** +** The event text identifies the invalid Log Mode command argument. Valid Log Mode command +** arguments are: #CFE_EVS_LOG_OVERWRITE or #CFE_EVS_LOG_DISCARD. +**/ +#define CFE_EVS_ERR_LOGMODE_EID 39 + +/** \brief 'Bit Mask = 0x\%X out of range: CC = \%lu' +** \event 'Bit Mask = 0x\%X out of range: CC = \%lu' +** +** \par Type: ERROR +** +** \par Cause: +** +** This event message is generated when the bit mask passed in is equal to zero or greater than 0x0F, because a +** bit mask of zero does nothing, and a bitmask of greater than 0x0F is invalid. +**/ +#define CFE_EVS_ERR_INVALID_BITMASK_EID 40 + +/** \brief 'App \%s not registered with Event Services. Unable to send event' +** \event 'App \%s not registered with Event Services. Unable to send event' +** +** \par Type: ERROR +** +** \par Cause: +** +** This event message is generated when an event message has been requested to be sent by an Application that +** has not registered itself with cFE Event Services. +**/ +#define CFE_EVS_ERR_UNREGISTERED_EVS_APP 41 + +/** \brief 'Max filter count reached, AppName = \%s, EventID = 0x\%08x: Filter locked until reset' +** \event 'Max filter count reached, AppName = \%s, EventID = 0x\%08x: Filter locked until reset' +** +** \par Type: INFORMATIONAL +** +** \par Cause: +** +** This event message is generated when the filtering count for a specific App and Event ID reaches +** CFE_EVS_MAX_FILTER_COUNT. The filtered event will no longer be received until the reset counter is reset via a +** \link #CFE_EVS_RESET_FILTER_CC "Reset an Event Filter for an Application" \endlink or a +** \link #CFE_EVS_RESET_ALL_FILTERS_CC "Reset All Event Filters for an Application" \endlink +** +** The \c AppName field identifies the Application and the \c EventID field identifies, in hex, the Event ID +** for the filter whose maxium was reached. +**/ +#define CFE_EVS_FILTER_MAX_EID 42 + +/** \brief 'Invalid cmd length: ID = 0x\%X, CC = \%d, Exp Len = \%d, Len = \%d' +** \event 'Invalid cmd length: ID = 0x\%X, CC = \%d, Exp Len = \%d, Len = \%d' +** +** \par Type: ERROR +** +** \par Cause: +** +** This event message is generated when a message with the #CFE_EVS_CMD_MID +** message ID has arrived but whose packet length does not match the expected +** length for the specified command code. +** +** The \c ID field in the event message specifies the Message ID (in hex), the \c CC field +** specifies the Command Code (in decimal), the \c Exp Len field specified the Expected +** Length (in decimal ), and \c Len specifies the message Length (in decimal) +** found in the message. +**/ +#define CFE_EVS_LEN_ERR_EID 43 + +#endif /* CFE_EVS_EVENTS_H */ diff --git a/modules/evs/fsw/inc/cfe_evs_msg.h b/modules/evs/fsw/inc/cfe_evs_msg.h new file mode 100644 index 000000000..9315bd830 --- /dev/null +++ b/modules/evs/fsw/inc/cfe_evs_msg.h @@ -0,0 +1,1287 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/** + * @file + * + * Title: Event Services Message definition header file Header File + * + * Purpose: + * Unit specification for Event services command codes and data structures. + * + * Design Notes: + * + * References: + * Flight Software Branch C Coding Standard Version 1.0a + * + */ + +#ifndef CFE_EVS_MSG_H +#define CFE_EVS_MSG_H + +/********************************** Include Files ************************************/ +#include "common_types.h" /* Basic data types */ +#include "cfe_msg_hdr.h" /* for header definitions */ +#include "cfe_evs_extern_typedefs.h" /* for EVS-specific types such as CFE_EVS_LogMode_Enum_t */ +#include "cfe_es_extern_typedefs.h" /* for CFE_ES_AppId_t type */ + +/** \name Event Services Command Codes */ +/** \{ */ + +/** \cfeevscmd Event Services No-Op +** +** \par Description +** This command performs no other function than to increment the +** command execution counter. The command may be used to verify +** general aliveness of the Event Services task. +** +** \cfecmdmnemonic \EVS_NOOP +** +** \par Command Structure +** #CFE_EVS_NoopCmd_t +** +** \par Command Verification +** Successful execution of this command may be verified with the +** following telemetry: +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** - The #CFE_EVS_NOOP_EID informational event message will +** be generated +** +** \par Error Conditions +** There are no error conditions for this command. If the Event +** Services receives the command, the event is sent (although it +** may be filtered by EVS itself) and the counter is incremented +** unconditionally. +** +** \par Criticality +** None +** +** \sa +*/ +#define CFE_EVS_NOOP_CC 0 + +/** \cfeevscmd Event Services Reset Counters +** +** \par Description +** This command resets the following counters within the Event +** Services housekeeping telemetry: +** - Command Execution Counter (\EVS_CMDPC) +** - Command Error Counter (\EVS_CMDEC) +** +** \cfecmdmnemonic \EVS_RESETCTRS +** +** \par Command Structure +** #CFE_EVS_ResetCountersCmd_t +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** - The #CFE_EVS_RSTCNT_EID debug event message will be +** generated +** +** \par Error Conditions +** There are no error conditions for this command. If the Event +** Services receives the command, the event is sent (although it +** may be filtered by EVS) and the counter is incremented +** unconditionally. +** +** \par Criticality +** This command is not inherently dangerous. However, it is +** possible for ground systems and on-board safing procedures +** to be designed such that they react to changes in the counter +** values that are reset by this command. +** +** \sa #CFE_EVS_RESET_APP_COUNTER_CC +*/ +#define CFE_EVS_RESET_COUNTERS_CC 1 + +/** \cfeevscmd Enable Event Type +** +** \par Description +** This command enables the command specified Event Type allowing event +** messages of this type to be sent through Event Service. An Event Type +** is defined to be a classification of an Event Message such as debug, +** informational, error and critical. This command is a global enable of a +** particular event type, it applies to all applications. +** +** \cfecmdmnemonic \EVS_ENAEVENTTYPE +** +** \par Command Structure +** #CFE_EVS_EnableEventTypeCmd_t +** The following bit positions apply to structure member named 'BitMask'. +** Bit 0 - Debug +** Bit 1 - Informational +** Bit 2 - Error +** Bit 3 - Critical +** A one in a bit position means the event type will be enabled (or unfiltered). +** A zero in a bit position means the filtering state is unchanged. +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** - The generation of #CFE_EVS_ENAEVTTYPE_EID debug message +** +** \par Error Conditions +** This command may fail for the following reason(s): +** +** Invalid Event Type selection +** +** Evidence of failure may be found in the following telemetry: +** - \b \c \EVS_CMDEC - command error counter will increment +** - An Error specific event message +** +** \par Criticality +** Enabling an event type is not particularly hazardous, as the result may +** be turning on necessary event messages and communication to the ground +** system. However, inappropriately enabling an event type could result +** in flooding of the system. +** +** \sa #CFE_EVS_DISABLE_EVENT_TYPE_CC, #CFE_EVS_ENABLE_APP_EVENT_TYPE_CC, +** #CFE_EVS_DISABLE_APP_EVENT_TYPE_CC, #CFE_EVS_ENABLE_APP_EVENTS_CC, #CFE_EVS_DISABLE_APP_EVENTS_CC +*/ +#define CFE_EVS_ENABLE_EVENT_TYPE_CC 2 + +/** \cfeevscmd Disable Event Type +** +** \par Description +** This command disables the command specified Event Type preventing event +** messages of this type to be sent through Event Service. An Event Type +** is defined to be a classification of an Event Message such as debug, +** informational, error and critical. This command is a global disable of a +** particular event type, it applies to all applications. +** +** \cfecmdmnemonic \EVS_DISEVENTTYPE +** +** \par Command Structure +** #CFE_EVS_DisableEventTypeCmd_t +** The following bit positions apply to structure member named 'BitMask'. +** Bit 0 - Debug +** Bit 1 - Informational +** Bit 2 - Error +** Bit 3 - Critical +** A one in a bit position means the event type will be disabled (or filtered). +** A zero in a bit position means the filtering state is unchanged. +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** +** - \b \c \EVS_CMDPC - command execution counter will +** increment + - The generation of #CFE_EVS_DISEVTTYPE_EID debug message +** +** \par Error Conditions +** This command may fail for the following reason(s): +** +** - Invalid Event Type selection + +** Evidence of failure may be found in the following telemetry: +** - \b \c \EVS_CMDEC - command error counter will increment +** - An Error specific event message +** +** \par Criticality +** Disabling an event type is not particularly hazardous, as the result +** may be shutting off unnecessary event messages and possible event +** flooding of the system. However, inappropriately disabling an event +** type could result in a loss of critical information and missed +** behavior for the ground system. +** +** \sa #CFE_EVS_ENABLE_EVENT_TYPE_CC, #CFE_EVS_ENABLE_APP_EVENT_TYPE_CC, +** #CFE_EVS_DISABLE_APP_EVENT_TYPE_CC, #CFE_EVS_ENABLE_APP_EVENTS_CC, #CFE_EVS_DISABLE_APP_EVENTS_CC +*/ +#define CFE_EVS_DISABLE_EVENT_TYPE_CC 3 + +/** \cfeevscmd Set Event Format Mode +** +** \par Description +** This command sets the event format mode to the command specified value. +** The event format mode may be either short or long. A short event format +** detaches the Event Data from the event message and only includes the +** following information in the event packet: Processor ID, Application ID, +** Event ID, and Event Type. Refer to section 5.3.3.4 for a description of +** the Event Service event packet contents. Event Data is defined to be data +** describing an Event that is supplied to the cFE Event Service. ASCII text +** strings are used as the primary format for Event Data because heritage +** ground systems use string compares as the basis for their automated alert +** systems. Two systems, ANSR and SERS were looked at for interface +** definitions. The short event format is used to accommodate experiences +** with limited telemetry bandwidth. The long event format includes all event +** information included within the short format along with the Event Data. +** +** \cfecmdmnemonic \EVS_SETEVTFMT +** +** \par Command Structure +** #CFE_EVS_SetEventFormatModeCmd_t +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** - The generation of #CFE_EVS_SETEVTFMTMOD_EID debug message +** +** \par Error Conditions +** This command may fail for the following reason(s): +** Invalid SB message (command) length +** Invalid MODE selection +** +** Evidence of failure may be found in the following telemetry: +** - \b \c \EVS_CMDEC - command error counter will increment +** - An Error specific event message +** +** \par Criticality +** Setting the event format mode is not particularly hazardous, as the +** result may be saving necessary bandwidth. However, inappropriately +** setting the event format mode could result in a loss of information +** and missed behavior for the ground system +** \sa +*/ +#define CFE_EVS_SET_EVENT_FORMAT_MODE_CC 4 + +/** \cfeevscmd Enable Application Event Type +** +** \par Description +** This command enables the command specified event type for the command +** specified application, allowing the application to send event messages +** of the command specified event type through Event Service. An Event +** Type is defined to be a classification of an Event Message such as +** debug, informational, critical, and error. +** Note: In order for this command to take effect, applications must be +** registered for Event Service. +** +** \cfecmdmnemonic \EVS_ENAAPPEVTTYPE +** +** \par Command Structure +** #CFE_EVS_EnableAppEventTypeCmd_t +** The following bit positions apply to structure member named 'BitMask'. +** Bit 0 - Debug +** Bit 1 - Informational +** Bit 2 - Error +** Bit 3 - Critical +** A one in a bit position means the event type will be enabled (or +** unfiltered) for the specified application. +** A zero in a bit position means the filtering state is unchanged for +** the specified application. +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** - The generation of #CFE_EVS_ENAAPPEVTTYPE_EID debug event message +** +** \par Error Conditions +** This command may fail for the following reason(s): +** - Invalid Event Type Selection +** +** Evidence of failure may be found in the following telemetry: +** - \b \c \EVS_CMDEC - command error counter will increment +** - An Error specific event message +** +** \par Criticality +** Enabling an application event type is not particularly hazardous, as +** the result may be turning on necessary event messages and +** communication to the ground system. However, inappropriately enabling +** an application's event type could result in flooding of the ground system. +** +** \sa #CFE_EVS_ENABLE_EVENT_TYPE_CC, #CFE_EVS_DISABLE_EVENT_TYPE_CC, +** #CFE_EVS_DISABLE_APP_EVENT_TYPE_CC, #CFE_EVS_ENABLE_APP_EVENTS_CC, #CFE_EVS_DISABLE_APP_EVENTS_CC +*/ +#define CFE_EVS_ENABLE_APP_EVENT_TYPE_CC 5 + +/** \cfeevscmd Disable Application Event Type +** +** \par Description +** This command disables the command specified event type for the command +** specified application, preventing the application from sending event +** messages of the command specified event type through Event Service. +** An Event Type is defined to be a classification of an Event Message such +** as debug, informational, critical, and error. Note: In order for this +** command to take effect, applications must be registered for Event Service. +** +** \cfecmdmnemonic \EVS_DISAPPEVTTYPE +** +** \par Command Structure +** #CFE_EVS_DisableAppEventTypeCmd_t +** The following bit positions apply to structure member named 'BitMask'. +** Bit 0 - Debug +** Bit 1 - Informational +** Bit 2 - Error +** Bit 3 - Critical +** A one in a bit position means the event type will be disabled (or +** filtered) for the specified application. +** A zero in a bit position means the filtering state is unchanged for +** the specified application. +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** - The generation of #CFE_EVS_DISAPPENTTYPE_EID debug event message +** - The clearing of the Event Type Active Flag in The Event Type Active Flag in EVS App Data File +** +** \par Error Conditions +** This command may fail for the following reason(s): +** - Invalid Event Type Selection +** +** Evidence of failure may be found in the following telemetry: +** - \b \c \EVS_CMDEC - command error counter will increment +** - An Error specific event message +** +** \par Criticality +** Disabling an application's event type is not particularly hazardous, +** as the result may be shutting off unnecessary event messages and +** possible event flooding of the system. However, inappropriately +** disabling an application's event type could result in a loss of critical +** information and missed behavior for the ground system. +** +** \sa #CFE_EVS_ENABLE_EVENT_TYPE_CC, #CFE_EVS_DISABLE_EVENT_TYPE_CC, #CFE_EVS_ENABLE_APP_EVENT_TYPE_CC, +** #CFE_EVS_ENABLE_APP_EVENTS_CC, #CFE_EVS_DISABLE_APP_EVENTS_CC +*/ +#define CFE_EVS_DISABLE_APP_EVENT_TYPE_CC 6 + +/** \cfeevscmd Enable Event Services for an Application +** +** \par Description +** This command enables the command specified application to send events +** through the Event Service. Note: In order for this command to take +** effect, applications must be registered for Event Service. +** +** \cfecmdmnemonic \EVS_ENAAPPEVGEN +** +** \par Command Structure +** #CFE_EVS_EnableAppEventsCmd_t +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** - The generation of #CFE_EVS_ENAAPPEVT_EID debug event message +** - The setting of the Active Flag in The Active Flag in EVS App Data File +** +** \par Error Conditions +** This command may fail for the following reason(s): +** - Invalid SB message (command) length +** - Application selected is not registered to receive Event Service +** - Application ID is out of range +** +** Evidence of failure may be found in the following telemetry: +** - \b \c \EVS_CMDEC - command error counter will increment +** - An Error specific event message +** +** \par Criticality +** Enabling an application events is not particularly hazardous, +** as the result may be turning on necessary event messages and +** communication to the ground system. However, inappropriately enabling +** an application's events could result in flooding of the ground system. +** +** \sa #CFE_EVS_ENABLE_EVENT_TYPE_CC, #CFE_EVS_DISABLE_EVENT_TYPE_CC, #CFE_EVS_ENABLE_APP_EVENT_TYPE_CC, +** #CFE_EVS_DISABLE_APP_EVENT_TYPE_CC, #CFE_EVS_DISABLE_APP_EVENTS_CC +*/ +#define CFE_EVS_ENABLE_APP_EVENTS_CC 7 + +/** \cfeevscmd Disable Event Services for an Application +** +** \par Description +** This command disables the command specified application from sending +** events through Event Service. Note: In order for this command to take +** effect, applications must be registered for Event Service. +** +** \cfecmdmnemonic \EVS_DISAPPEVGEN +** +** \par Command Structure +** #CFE_EVS_DisableAppEventsCmd_t +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** - The generation of #CFE_EVS_DISAPPEVT_EID debug event message +** +** \par Error Conditions +** This command may fail for the following reason(s): +** - Invalid SB message (command) length +** - Application selected is not registered to receive Event Service +** - Application ID is out of range +** +** Evidence of failure may be found in the following telemetry: +** - \b \c \EVS_CMDEC - command error counter will increment +** - An Error specific event message +** +** \par Criticality +** Disabling an application's events is not particularly hazardous, as the +** result may be shutting off unnecessary event messages and possible event +** flooding of the system. However, inappropriately disabling an +** application's events could result in a loss of critical information and +** missed behavior for the ground system. +** +** \sa #CFE_EVS_ENABLE_EVENT_TYPE_CC, #CFE_EVS_DISABLE_EVENT_TYPE_CC, #CFE_EVS_ENABLE_APP_EVENT_TYPE_CC, +** #CFE_EVS_DISABLE_APP_EVENT_TYPE_CC, #CFE_EVS_ENABLE_APP_EVENTS_CC +*/ +#define CFE_EVS_DISABLE_APP_EVENTS_CC 8 + +/** \cfeevscmd Reset Application Event Counters +** +** \par Description +** This command sets the command specified application's event counter to zero. +** Note: In order for this command to take effect, applications must be registered +** for Event Service. +** +** \cfecmdmnemonic \EVS_RSTAPPCTRS +** +** \par Command Structure +** #CFE_EVS_ResetAppCounterCmd_t +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** - The generation of #CFE_EVS_RSTEVTCNT_EID debug event message +** +** \par Error Conditions +** This command may fail for the following reason(s): +** - Invalid SB message (command) length +** - Application selected is not registered to receive Event Service +** - Application ID is out of range +** +** Evidence of failure may be found in the following telemetry: +** - \b \c \EVS_CMDEC - command error counter will increment +** - An Error specific event message +** +** \par Criticality +** This command is not inherently dangerous. However, it is possible for +** ground systems and on-board safing procedures to be designed such that +** they react to changes in the counter value that is reset by this command. +** +** \sa #CFE_EVS_RESET_COUNTERS_CC +*/ +#define CFE_EVS_RESET_APP_COUNTER_CC 9 + +/** \cfeevscmd Set Application Event Filter +** +** \par Description +** This command sets the command specified application's event filter mask +** to the command specified value for the command specified event. Note: +** In order for this command to take effect, applications must be +** registered for Event Service. +** +** \cfecmdmnemonic \EVS_SETBINFLTRMASK +** +** \par Command Structure +** #CFE_EVS_SetFilterCmd_t +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** - The generation of #CFE_EVS_SETFILTERMSK_EID debug event message +** +** \par Error Conditions +** This command may fail for the following reason(s): +** - Invalid SB message (command) length +** - Application selected is not registered to receive Event Service +** - Application ID is out of range +** +** Evidence of failure may be found in the following telemetry: +** - \b \c \EVS_CMDEC - command error counter will increment +** - An Error specific event message +** +** \par Criticality +** Setting an application event filter mask is not particularly hazardous, +** as the result may be shutting off unnecessary event messages and possible +** event flooding of the system. However, inappropriately setting an +** application's event filter mask could result in a loss of critical +** information and missed behavior for the ground system or flooding of the +** ground system. +** +** \sa #CFE_EVS_RESET_FILTER_CC, #CFE_EVS_RESET_ALL_FILTERS_CC, #CFE_EVS_ADD_EVENT_FILTER_CC, +*#CFE_EVS_DELETE_EVENT_FILTER_CC +*/ +#define CFE_EVS_SET_FILTER_CC 10 + +/** \cfeevscmd Enable Event Services Output Ports +** +** \par Description +** This command enables the command specified port to output event messages +** +** \cfecmdmnemonic \EVS_ENAPORT +** +** \par Command Structure +** #CFE_EVS_EnablePortsCmd_t +** The following bit positions apply to structure member named 'BitMask'. +** Bit 0 - Port 1 +** Bit 1 - Port 2 +** Bit 2 - Port 3 +** Bit 3 - Port 4 +** A one in a bit position means the port will be enabled. +** A zero in a bit position means the port state is unchanged. +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** - The generation of #CFE_EVS_ENAPORT_EID debug event message +** +** \par Error Conditions +** This command may fail for the following reason(s): +** - Invalid SB message (command) length +** - Invalid PORT selection +** +** Evidence of failure may be found in the following telemetry: +** - \b \c \EVS_CMDEC - command error counter will increment +** - An Error specific event message +** +** \par Criticality +** None. +** +** \sa #CFE_EVS_DISABLE_PORTS_CC +*/ +#define CFE_EVS_ENABLE_PORTS_CC 11 + +/** \cfeevscmd Disable Event Services Output Ports +** +** \par Description +** This command disables the specified port from outputting event messages. +** +** \cfecmdmnemonic \EVS_DISPORT +** +** \par Command Structure +** #CFE_EVS_DisablePortsCmd_t +** The following bit positions apply to structure member named 'BitMask'. +** Bit 0 - Port 1 +** Bit 1 - Port 2 +** Bit 2 - Port 3 +** Bit 3 - Port 4 +** A one in a bit position means the port will be disabled. +** A zero in a bit position means the port state is unchanged. +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** - The generation of #CFE_EVS_DISPORT_EID debug event message +** +** \par Error Conditions +** This command may fail for the following reason(s): +** - Invalid SB message (command) length +** - Invalid PORT selection +** +** Evidence of failure may be found in the following telemetry: +** - \b \c \EVS_CMDEC - command error counter will increment +** - An Error specific event message +** +** \par Criticality +** None. +** +** \sa #CFE_EVS_ENABLE_PORTS_CC +*/ +#define CFE_EVS_DISABLE_PORTS_CC 12 + +/** \cfeevscmd Reset an Event Filter for an Application +** +** \par Description +** This command resets the command specified application's event filter for +** the command specified event ID. Note: In order for this command to take +** effect, applications must be registered for Event Service. +** +** \cfecmdmnemonic \EVS_RSTBINFLTRCTR +** +** \par Command Structure +** #CFE_EVS_ResetFilterCmd_t +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** - The generation of #CFE_EVS_RSTFILTER_EID debug event message +** +** \par Error Conditions +** This command may fail for the following reason(s): +** - Invalid SB message (command) length +** - Application selected is not registered to receive Event Service +** - Application ID is out of range +** +** Evidence of failure may be found in the following telemetry: +** - \b \c \EVS_CMDEC - command error counter will increment +** - An Error specific event message +** +** \par Criticality +** None. +** +** \sa #CFE_EVS_SET_FILTER_CC, #CFE_EVS_RESET_ALL_FILTERS_CC, #CFE_EVS_ADD_EVENT_FILTER_CC, +*#CFE_EVS_DELETE_EVENT_FILTER_CC +*/ +#define CFE_EVS_RESET_FILTER_CC 13 + +/** \cfeevscmd Reset All Event Filters for an Application +** +** \par Description +** This command resets all of the command specified applications event +** filters. Note: In order for this command to take effect, applications +** must be registered for Event Service. +** +** \cfecmdmnemonic \EVS_RSTALLFLTRS +** +** \par Command Structure +** #CFE_EVS_ResetAllFiltersCmd_t +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** - The generation of #CFE_EVS_RSTALLFILTER_EID debug event message +** +** \par Error Conditions +** This command may fail for the following reason(s): +** - Invalid SB message (command) length +** - Application selected is not registered to receive Event Service +** - Application ID is out of range +** +** Evidence of failure may be found in the following telemetry: +** - \b \c \EVS_CMDEC - command error counter will increment +** - An Error specific event message +** +** \par Criticality +** None. +** +** \sa #CFE_EVS_SET_FILTER_CC, #CFE_EVS_RESET_FILTER_CC, #CFE_EVS_ADD_EVENT_FILTER_CC, #CFE_EVS_DELETE_EVENT_FILTER_CC +*/ +#define CFE_EVS_RESET_ALL_FILTERS_CC 14 + +/** \cfeevscmd Add Application Event Filter +** +** \par Description +** This command adds the given filter for the given application identifier and event identifier. +** Note: In order for this command to take effect, applications +** must be registered for Event Service. +** +** \cfecmdmnemonic \EVS_ADDEVTFLTR +** +** \par Command Structure +** #CFE_EVS_AddEventFilterCmd_t +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** - The generation of #CFE_EVS_ADDFILTER_EID debug event message +** +** \par Error Conditions +** This command may fail for the following reason(s): +** - Invalid SB message (command) length +** - Application selected is not registered to receive Event Service +** - Application ID is out of range +** +** Evidence of failure may be found in the following telemetry: +** - \b \c \EVS_CMDEC - command error counter will increment +** - An Error specific event message +** +** \par Criticality +** None. +** +** \sa #CFE_EVS_SET_FILTER_CC, #CFE_EVS_RESET_FILTER_CC, #CFE_EVS_RESET_ALL_FILTERS_CC, #CFE_EVS_DELETE_EVENT_FILTER_CC +*/ +#define CFE_EVS_ADD_EVENT_FILTER_CC 15 + +/** \cfeevscmd Delete Application Event Filter +** +** \par Description +** This command removes the given filter for the given application identifier and event identifier. +** Note: In order for this command to take effect, applications +** must be registered for Event Service. +** +** \cfecmdmnemonic \EVS_DELEVTFLTR +** +** \par Command Structure +** #CFE_EVS_DeleteEventFilterCmd_t +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** - The generation of #CFE_EVS_DELFILTER_EID debug event message +** +** \par Error Conditions +** This command may fail for the following reason(s): +** - Invalid SB message (command) length +** - Application selected is not registered to receive Event Service +** - Application ID is out of range +** +** Evidence of failure may be found in the following telemetry: +** - \b \c \EVS_CMDEC - command error counter will increment +** - An Error specific event message +** +** \par Criticality +** None. +** +** \sa #CFE_EVS_SET_FILTER_CC, #CFE_EVS_RESET_FILTER_CC, #CFE_EVS_RESET_ALL_FILTERS_CC, #CFE_EVS_ADD_EVENT_FILTER_CC +*/ +#define CFE_EVS_DELETE_EVENT_FILTER_CC 16 + +/** \cfeevscmd Write Event Services Application Information to File +** +** \par Description +** This command writes all application data to a file for all applications that +** have registered with the EVS. The application data includes the Application ID, +** Active Flag, Event Count, Event Types Active Flag, and Filter Data. +** +** \cfecmdmnemonic \EVS_WRITEAPPDATA2FILE +** +** \par Command Structure +** #CFE_EVS_WriteAppDataFileCmd_t +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** - The generation of #CFE_EVS_WRDAT_EID debug event message +** - The generation of the file written to +** +** \par Error Conditions +** This command may fail for the following reason(s): +** - Invalid SB message (command) length +** +** Evidence of failure may be found in the following telemetry: +** - \b \c \EVS_CMDEC - command error counter will increment +** - An Error specific event message +** +** \par Criticality +** Writing a file is not particularly hazardous, but if proper file management is not +** taken, then the file system can fill up if this command is used repeatedly. +** +** \sa #CFE_EVS_WRITE_LOG_DATA_FILE_CC, #CFE_EVS_SET_LOG_MODE_CC +*/ +#define CFE_EVS_WRITE_APP_DATA_FILE_CC 17 + +/** \cfeevscmd Write Event Log to File +** +** \par Description +** This command requests the Event Service to generate a file containing +** the contents of the local event log. +** +** \cfecmdmnemonic \EVS_WRITELOG2FILE +** +** \par Command Structure +** #CFE_EVS_WriteLogDataFileCmd_t +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** - The generation of #CFE_EVS_WRLOG_EID debug event message +** +** \par Error Conditions +** This command may fail for the following reason(s): +** - Invalid SB message (command) length +** +** Evidence of failure may be found in the following telemetry: +** - \b \c \EVS_CMDEC - command error counter will increment +** - An Error specific event message +** +** \par Criticality +** Writing a file is not particularly hazardous, but if proper file management is not +** taken, then the file system can fill up if this command is used repeatedly. +** +** \sa #CFE_EVS_WRITE_APP_DATA_FILE_CC, #CFE_EVS_SET_LOG_MODE_CC, #CFE_EVS_CLEAR_LOG_CC +*/ +#define CFE_EVS_WRITE_LOG_DATA_FILE_CC 18 + +/** \cfeevscmd Set Logging Mode +** +** \par Description +** This command sets the logging mode to the command specified value. +** +** \cfecmdmnemonic \EVS_SETLOGMODE +** +** \par Command Structure +** #CFE_EVS_SetLogModeCmd_t +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** - The generation of #CFE_EVS_LOGMODE_EID debug event message +** +** \par Error Conditions +** This command may fail for the following reason(s): +** - Invalid SB message (command) length +** - Invalid MODE selected +** +** Evidence of failure may be found in the following telemetry: +** - \b \c \EVS_CMDEC - command error counter will increment +** - An Error specific event message +** +** \par Criticality +** Setting the event logging mode is not particularly hazardous, as the +** result may be saving valuable event data. However, inappropriately +** setting the log mode could result in a loss of critical information. +** Note: the event log is a back-up log to the on-board recorder. +** +** \sa #CFE_EVS_WRITE_LOG_DATA_FILE_CC, #CFE_EVS_CLEAR_LOG_CC +*/ +#define CFE_EVS_SET_LOG_MODE_CC 19 + +/** \cfeevscmd Clear Event Log +** +** \par Description +** This command clears the contents of the local event log. +** +** \cfecmdmnemonic \EVS_CLRLOG +** +** \par Command Structure +** #CFE_EVS_ClearLogCmd_t +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: +** - \b \c \EVS_CMDPC - command execution counter will +** increment +** +** \par Error Conditions +** This command may fail for the following reason(s): +** - Invalid SB message (command) length +** +** Evidence of failure may be found in the following telemetry: +** - \b \c \EVS_CMDEC - command error counter will increment +** - An Error specific event message +** +** \par Criticality +** Clearing the local event log is not particularly hazardous, as the +** result may be making available space to record valuable event data. +** However, inappropriately clearing the local event log could result +** in a loss of critical information. Note: the event log is a back-up +** log to the on-board recorder. +** +** \sa #CFE_EVS_WRITE_LOG_DATA_FILE_CC, #CFE_EVS_SET_LOG_MODE_CC +*/ +#define CFE_EVS_CLEAR_LOG_CC 20 +/** \} */ + +/* Event Type bit masks */ +#define CFE_EVS_DEBUG_BIT 0x0001 +#define CFE_EVS_INFORMATION_BIT 0x0002 +#define CFE_EVS_ERROR_BIT 0x0004 +#define CFE_EVS_CRITICAL_BIT 0x0008 + +/* Output Port bit masks */ +#define CFE_EVS_PORT1_BIT 0x0001 +#define CFE_EVS_PORT2_BIT 0x0002 +#define CFE_EVS_PORT3_BIT 0x0004 +#define CFE_EVS_PORT4_BIT 0x0008 + +/* EVS Log Modes */ +#define CFE_EVS_LOG_OVERWRITE 0 +#define CFE_EVS_LOG_DISCARD 1 + +/****************** Structure Definitions *********************/ + +/** +** \brief Command with no additional arguments +**/ +typedef struct CFE_EVS_NoArgsCmd +{ + CFE_MSG_CommandHeader_t CmdHeader; /**< \brief Command header */ +} CFE_EVS_NoArgsCmd_t; + +/* + * The NoArgsCmd is shared by several EVS command handlers. + * Create a unique type for each one so the prototypes will follow the naming pattern, + * allowing each command to evolve independently. + */ +typedef CFE_EVS_NoArgsCmd_t CFE_EVS_NoopCmd_t; +typedef CFE_EVS_NoArgsCmd_t CFE_EVS_ResetCountersCmd_t; +typedef CFE_EVS_NoArgsCmd_t CFE_EVS_ClearLogCmd_t; + +/** +** \brief Write Event Log to File Command Payload +** +** For command details, see #CFE_EVS_WRITE_LOG_DATA_FILE_CC +** +**/ +typedef struct CFE_EVS_LogFileCmd_Payload +{ + char LogFilename[CFE_MISSION_MAX_PATH_LEN]; /**< \brief Filename where log data is to be written */ +} CFE_EVS_LogFileCmd_Payload_t; + +/** + * \brief Write Event Log to File Command + */ +typedef struct CFE_EVS_WriteLogDataFileCmd +{ + CFE_MSG_CommandHeader_t CmdHeader; /**< \brief Command header */ + CFE_EVS_LogFileCmd_Payload_t Payload; /**< \brief Command payload */ +} CFE_EVS_WriteLogDataFileCmd_t; + +/** +** \brief Write Event Services Application Information to File Command Payload +** +** For command details, see #CFE_EVS_WRITE_APP_DATA_FILE_CC +** +**/ +typedef struct CFE_EVS_AppDataCmd_Payload +{ + char AppDataFilename[CFE_MISSION_MAX_PATH_LEN]; /**< \brief Filename where applicaton data is to be written */ +} CFE_EVS_AppDataCmd_Payload_t; + +/** + * \brief Write Event Services Application Information to File Command + */ +typedef struct CFE_EVS_WriteAppDataFileCmd +{ + CFE_MSG_CommandHeader_t CmdHeader; /**< \brief Command header */ + CFE_EVS_AppDataCmd_Payload_t Payload; /**< \brief Command payload */ +} CFE_EVS_WriteAppDataFileCmd_t; + +/** +** \brief Set Log Mode Command Payload +** +** For command details, see #CFE_EVS_SET_LOG_MODE_CC +** +**/ +typedef struct CFE_EVS_SetLogMode_Payload +{ + CFE_EVS_LogMode_Enum_t LogMode; /**< \brief Mode to use in the command*/ + uint8 Spare; /**< \brief Pad to even byte*/ +} CFE_EVS_SetLogMode_Payload_t; + +/** + * \brief Set Log Mode Command + */ +typedef struct CFE_EVS_SetLogModeCmd +{ + CFE_MSG_CommandHeader_t CmdHeader; /**< \brief Command header */ + CFE_EVS_SetLogMode_Payload_t Payload; /**< \brief Command payload */ +} CFE_EVS_SetLogModeCmd_t; + +/** +** \brief Set Event Format Mode Command Payload +** +** For command details, see #CFE_EVS_SET_EVENT_FORMAT_MODE_CC +** +**/ +typedef struct CFE_EVS_SetEventFormatCode_Payload +{ + CFE_EVS_MsgFormat_Enum_t MsgFormat; /**< \brief Mode to use in the command*/ + uint8 Spare; /**< \brief Pad to even byte*/ +} CFE_EVS_SetEventFormatMode_Payload_t; + +/** + * \brief Set Event Format Mode Command + */ +typedef struct CFE_EVS_SetEventFormatModeCmd +{ + CFE_MSG_CommandHeader_t CmdHeader; /**< \brief Command header */ + CFE_EVS_SetEventFormatMode_Payload_t Payload; /**< \brief Command payload */ +} CFE_EVS_SetEventFormatModeCmd_t; + +/** +** \brief Generic Bitmask Command Payload +** +** For command details, see #CFE_EVS_ENABLE_EVENT_TYPE_CC, #CFE_EVS_DISABLE_EVENT_TYPE_CC, +** #CFE_EVS_ENABLE_PORTS_CC and/or #CFE_EVS_DISABLE_PORTS_CC +** +**/ +typedef struct CFE_EVS_BitMaskCmd_Payload +{ + uint8 BitMask; /**< \brief BitMask to use in the command */ + uint8 Spare; /**< \brief Pad to even byte*/ +} CFE_EVS_BitMaskCmd_Payload_t; + +/** + * \brief Generic Bitmask Command + */ +typedef struct CFE_EVS_BitMaskCmd +{ + CFE_MSG_CommandHeader_t CmdHeader; /**< \brief Command header */ + CFE_EVS_BitMaskCmd_Payload_t Payload; /**< \brief Command payload */ +} CFE_EVS_BitMaskCmd_t; + +/* + * The CFE_EVS_BitMaskCmd_t is shared by several EVS command handlers. + * Create a unique type for each one so the prototypes will follow the naming pattern, + * allowing each command to evolve independently. + */ +typedef CFE_EVS_BitMaskCmd_t CFE_EVS_EnablePortsCmd_t; +typedef CFE_EVS_BitMaskCmd_t CFE_EVS_DisablePortsCmd_t; +typedef CFE_EVS_BitMaskCmd_t CFE_EVS_EnableEventTypeCmd_t; +typedef CFE_EVS_BitMaskCmd_t CFE_EVS_DisableEventTypeCmd_t; + +/** +** \brief Generic App Name Command Payload +** +** For command details, see #CFE_EVS_ENABLE_APP_EVENTS_CC, #CFE_EVS_DISABLE_APP_EVENTS_CC, +** #CFE_EVS_RESET_APP_COUNTER_CC and/or #CFE_EVS_RESET_ALL_FILTERS_CC +** +**/ +typedef struct CFE_EVS_AppNameCmd_Payload +{ + char AppName[CFE_MISSION_MAX_API_LEN]; /**< \brief Application name to use in the command*/ +} CFE_EVS_AppNameCmd_Payload_t; + +/** + * \brief Generic App Name Command + */ +typedef struct CFE_EVS_AppNameCmd +{ + CFE_MSG_CommandHeader_t CmdHeader; /**< \brief Command header */ + CFE_EVS_AppNameCmd_Payload_t Payload; /**< \brief Command payload */ +} CFE_EVS_AppNameCmd_t; + +/* + * The CFE_EVS_AppNameCmd_t is shared by several EVS command handlers. + * Create a unique type for each one so the prototypes will follow the naming pattern, + * allowing each command to evolve independently. + */ +typedef CFE_EVS_AppNameCmd_t CFE_EVS_EnableAppEventsCmd_t; +typedef CFE_EVS_AppNameCmd_t CFE_EVS_DisableAppEventsCmd_t; +typedef CFE_EVS_AppNameCmd_t CFE_EVS_ResetAppCounterCmd_t; +typedef CFE_EVS_AppNameCmd_t CFE_EVS_ResetAllFiltersCmd_t; + +/** +** \brief Generic App Name and Event ID Command Payload +** +** For command details, see #CFE_EVS_RESET_FILTER_CC and #CFE_EVS_DELETE_EVENT_FILTER_CC +** +**/ +typedef struct CFE_EVS_AppNameEventIDCmd_Payload +{ + char AppName[CFE_MISSION_MAX_API_LEN]; /**< \brief Application name to use in the command*/ + uint16 EventID; /**< \brief Event ID to use in the command*/ +} CFE_EVS_AppNameEventIDCmd_Payload_t; + +/** + * \brief Generic App Name and Event ID Command + */ +typedef struct CFE_EVS_AppNameEventIDCmd +{ + CFE_MSG_CommandHeader_t CmdHeader; /**< \brief Command header */ + CFE_EVS_AppNameEventIDCmd_Payload_t Payload; /**< \brief Command payload */ +} CFE_EVS_AppNameEventIDCmd_t; + +/* + * The CFE_EVS_AppNameEventIDCmd_t is shared by several EVS command handlers. + * Create a unique type for each one so the prototypes will follow the naming pattern, + * allowing each command to evolve independently. + */ +typedef CFE_EVS_AppNameEventIDCmd_t CFE_EVS_ResetFilterCmd_t; +typedef CFE_EVS_AppNameEventIDCmd_t CFE_EVS_DeleteEventFilterCmd_t; + +/** +** \brief Generic App Name and Bitmask Command Payload +** +** For command details, see #CFE_EVS_ENABLE_APP_EVENT_TYPE_CC and/or #CFE_EVS_DISABLE_APP_EVENT_TYPE_CC +** +**/ +typedef struct CFE_EVS_AppNameBitMaskCmd_Payload +{ + char AppName[CFE_MISSION_MAX_API_LEN]; /**< \brief Application name to use in the command*/ + uint8 BitMask; /**< \brief BitMask to use in the command*/ + uint8 Spare; /**< \brief Pad to even byte*/ +} CFE_EVS_AppNameBitMaskCmd_Payload_t; + +/** + * \brief Generic App Name and Bitmask Command + */ +typedef struct CFE_EVS_AppNameBitMaskCmd +{ + CFE_MSG_CommandHeader_t CmdHeader; /**< \brief Command header */ + CFE_EVS_AppNameBitMaskCmd_Payload_t Payload; /**< \brief Command payload */ +} CFE_EVS_AppNameBitMaskCmd_t; + +/* + * The CFE_EVS_AppNameBitMaskCmd_t is shared by several EVS command handlers. + * Create a unique type for each one so the prototypes will follow the naming pattern, + * allowing each command to evolve independently. + */ +typedef CFE_EVS_AppNameBitMaskCmd_t CFE_EVS_EnableAppEventTypeCmd_t; +typedef CFE_EVS_AppNameBitMaskCmd_t CFE_EVS_DisableAppEventTypeCmd_t; + +/** +** \brief Generic App Name, Event ID, Mask Command Payload +** +** For command details, see #CFE_EVS_SET_FILTER_CC, #CFE_EVS_ADD_EVENT_FILTER_CC +** and/or #CFE_EVS_DELETE_EVENT_FILTER_CC +** +**/ +typedef struct CFE_EVS_AppNameEventIDMaskCmd_Payload +{ + char AppName[CFE_MISSION_MAX_API_LEN]; /**< \brief Application name to use in the command*/ + uint16 EventID; /**< \brief Event ID to use in the command*/ + uint16 Mask; /**< \brief Mask to use in the command */ +} CFE_EVS_AppNameEventIDMaskCmd_Payload_t; + +/** + * \brief Generic App Name, Event ID, Mask Command + */ +typedef struct CFE_EVS_AppNameEventIDMaskCmd +{ + CFE_MSG_CommandHeader_t CmdHeader; /**< \brief Command header */ + CFE_EVS_AppNameEventIDMaskCmd_Payload_t Payload; /**< \brief Command payload */ +} CFE_EVS_AppNameEventIDMaskCmd_t; + +/* + * The CFE_EVS_AppNameEventIDMaskCmd_t is shared by several EVS command handlers. + * Create a unique type for each one so the prototypes will follow the naming pattern, + * allowing each command to evolve independently. + */ +typedef CFE_EVS_AppNameEventIDMaskCmd_t CFE_EVS_AddEventFilterCmd_t; +typedef CFE_EVS_AppNameEventIDMaskCmd_t CFE_EVS_SetFilterCmd_t; + +/*************************************************************************/ +/**********************************/ +/* Telemetry Message Data Formats */ +/**********************************/ +typedef struct CFE_EVS_AppTlmData +{ + CFE_ES_AppId_t AppID; /**< \cfetlmmnemonic \EVS_APPID + \brief Numerical application identifier */ + uint16 AppMessageSentCounter; /**< \cfetlmmnemonic \EVS_APPMSGSENTC + \brief Application message sent counter */ + uint8 AppEnableStatus; /**< \cfetlmmnemonic \EVS_APPENASTAT + \brief Application event service enable status */ + uint8 Padding; /**< \cfetlmmnemonic \EVS_SPARE2ALIGN3 + \brief Padding for 32 bit boundary */ + +} CFE_EVS_AppTlmData_t; + +/** +** \cfeevstlm Event Services Housekeeping Telemetry Packet +**/ +typedef struct CFE_EVS_HousekeepingTlm_Payload +{ + uint8 CommandCounter; /**< \cfetlmmnemonic \EVS_CMDPC + \brief EVS Command Counter */ + uint8 CommandErrorCounter; /**< \cfetlmmnemonic \EVS_CMDEC + \brief EVS Command Error Counter */ + uint8 MessageFormatMode; /**< \cfetlmmnemonic \EVS_MSGFMTMODE + \brief Event message format mode (short/long) */ + uint8 MessageTruncCounter; /**< \cfetlmmnemonic \EVS_MSGTRUNC + \brief Event message truncation counter */ + + uint8 UnregisteredAppCounter; /**< \cfetlmmnemonic \EVS_UNREGAPPC + \brief Unregistered application message send counter */ + uint8 OutputPort; /**< \cfetlmmnemonic \EVS_OUTPUTPORT + \brief Output port mask */ + uint8 LogFullFlag; /**< \cfetlmmnemonic \EVS_LOGFULL + \brief Local event log full flag */ + uint8 LogMode; /**< \cfetlmmnemonic \EVS_LOGMODE + \brief Local event logging mode (overwrite/discard) */ + + uint16 MessageSendCounter; /**< \cfetlmmnemonic \EVS_MSGSENTC + \brief Event message send counter */ + uint16 LogOverflowCounter; /**< \cfetlmmnemonic \EVS_LOGOVERFLOWC + \brief Local event log overflow counter */ + + uint8 LogEnabled; /**< \cfetlmmnemonic \EVS_LOGENABLED + \brief Current event log enable/disable state */ + uint8 Spare1; /**< \cfetlmmnemonic \EVS_HK_SPARE1 + \brief Padding for 32 bit boundary */ + uint8 Spare2; /**< \cfetlmmnemonic \EVS_HK_SPARE2 + \brief Padding for 32 bit boundary */ + uint8 Spare3; /**< \cfetlmmnemonic \EVS_HK_SPARE3 + \brief Padding for 32 bit boundary */ + + CFE_EVS_AppTlmData_t AppData[CFE_MISSION_ES_MAX_APPLICATIONS]; /**< \cfetlmmnemonic \EVS_APP + \brief Array of registered application table data */ + +} CFE_EVS_HousekeepingTlm_Payload_t; + +typedef struct CFE_EVS_HousekeepingTlm +{ + CFE_MSG_TelemetryHeader_t TlmHeader; /**< \brief Telemetry header */ + CFE_EVS_HousekeepingTlm_Payload_t Payload; /**< \brief Telemetry payload */ +} CFE_EVS_HousekeepingTlm_t; + +/** Telemetry packet structures */ + +typedef struct CFE_EVS_PacketID +{ + char AppName[CFE_MISSION_MAX_API_LEN]; /**< \cfetlmmnemonic \EVS_APPNAME + \brief Application name */ + uint16 EventID; /**< \cfetlmmnemonic \EVS_EVENTID + \brief Numerical event identifier */ + uint16 EventType; /**< \cfetlmmnemonic \EVS_EVENTTYPE + \brief Numerical event type identifier */ + uint32 SpacecraftID; /**< \cfetlmmnemonic \EVS_SCID + \brief Spacecraft identifier */ + uint32 ProcessorID; /**< \cfetlmmnemonic \EVS_PROCESSORID + \brief Numerical processor identifier */ + +} CFE_EVS_PacketID_t; + +/** +** \cfeevstlm Event Message Telemetry Packet (Long format) +**/ +typedef struct CFE_EVS_LongEventTlm_Payload +{ + CFE_EVS_PacketID_t PacketID; /**< \brief Event packet information */ + char Message[CFE_MISSION_EVS_MAX_MESSAGE_LENGTH]; /**< \cfetlmmnemonic \EVS_EVENT + \brief Event message string */ + uint8 Spare1; /**< \cfetlmmnemonic \EVS_SPARE1 + \brief Structure padding */ + uint8 Spare2; /**< \cfetlmmnemonic \EVS_SPARE2 + \brief Structure padding */ +} CFE_EVS_LongEventTlm_Payload_t; + +/** +** \cfeevstlm Event Message Telemetry Packet (Short format) +**/ +typedef struct CFE_EVS_ShortEventTlm_Payload +{ + CFE_EVS_PacketID_t PacketID; /**< \brief Event packet information */ + +} CFE_EVS_ShortEventTlm_Payload_t; + +typedef struct CFE_EVS_LongEventTlm +{ + CFE_MSG_TelemetryHeader_t TlmHeader; /**< \brief Telemetry header */ + CFE_EVS_LongEventTlm_Payload_t Payload; /**< \brief Telemetry payload */ + +} CFE_EVS_LongEventTlm_t; + +typedef struct CFE_EVS_ShortEventTlm +{ + CFE_MSG_TelemetryHeader_t TlmHeader; /**< \brief Telemetry header */ + CFE_EVS_ShortEventTlm_Payload_t Payload; /**< \brief Telemetry payload */ + +} CFE_EVS_ShortEventTlm_t; + +#endif /* CFE_EVS_MSG_H */ diff --git a/modules/evs/fsw/src/cfe_evs.c b/modules/evs/fsw/src/cfe_evs.c new file mode 100644 index 000000000..405635603 --- /dev/null +++ b/modules/evs/fsw/src/cfe_evs.c @@ -0,0 +1,324 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** +** File: cfe_evs.c +** +** Title: Event Services API library +** +** Purpose: This module defines the library functions of the +** Event Services API +** +*/ + +/* Include Files */ +#include "cfe_evs_module_all.h" /* All EVS internal definitions and API */ + +#include +#include + +/* External Data */ + +/* Local Function Prototypes */ + +/* Function Definitions */ + +/* +** Function: CFE_EVS_Register - See API and header file for details +*/ +int32 CFE_EVS_Register(const void *Filters, uint16 NumEventFilters, uint16 FilterScheme) +{ + uint16 FilterLimit; + uint16 i; + int32 Status; + CFE_ES_AppId_t AppID; + CFE_EVS_BinFilter_t *AppFilters; + EVS_AppData_t * AppDataPtr; + + /* Query and verify the caller's AppID */ + Status = EVS_GetCurrentContext(&AppDataPtr, &AppID); + if (Status == CFE_SUCCESS) + { + /* Clear and configure entry */ + memset(AppDataPtr, 0, sizeof(EVS_AppData_t)); + + /* Verify filter arguments */ + if (FilterScheme != CFE_EVS_EventFilter_BINARY) + { + Status = CFE_EVS_UNKNOWN_FILTER; + } + else if ((NumEventFilters != 0) && (Filters == NULL)) + { + Status = CFE_ES_BAD_ARGUMENT; + } + else + { + /* Initialize application event data */ + AppDataPtr->ActiveFlag = true; + AppDataPtr->EventTypesActiveFlag = CFE_PLATFORM_EVS_DEFAULT_TYPE_FLAG; + + /* Set limit for number of provided filters */ + if (NumEventFilters < CFE_PLATFORM_EVS_MAX_EVENT_FILTERS) + { + FilterLimit = NumEventFilters; + } + else + { + FilterLimit = CFE_PLATFORM_EVS_MAX_EVENT_FILTERS; + CFE_ES_WriteToSysLog("CFE_EVS_Register: Filter limit truncated to %d\n", (int)FilterLimit); + } + + if (Filters != NULL) + { + AppFilters = (CFE_EVS_BinFilter_t *)Filters; + + /* Copy provided filters */ + for (i = 0; i < FilterLimit; i++) + { + AppDataPtr->BinFilters[i].EventID = AppFilters[i].EventID; + AppDataPtr->BinFilters[i].Mask = AppFilters[i].Mask; + AppDataPtr->BinFilters[i].Count = 0; + } + } + + /* Initialize remainder of filters as unused */ + for (i = FilterLimit; i < CFE_PLATFORM_EVS_MAX_EVENT_FILTERS; i++) + { + AppDataPtr->BinFilters[i].EventID = CFE_EVS_FREE_SLOT; + AppDataPtr->BinFilters[i].Mask = 0; + AppDataPtr->BinFilters[i].Count = 0; + } + + EVS_AppDataSetUsed(AppDataPtr, AppID); + } + } + + return (Status); + +} /* End CFE_EVS_Register */ + +/* +** Function: CFE_EVS_Unregister - See API and header file for details +*/ +int32 CFE_EVS_Unregister(void) +{ + int32 Status; + CFE_ES_AppId_t AppID; + EVS_AppData_t *AppDataPtr; + + /* Query and verify the caller's AppID */ + Status = EVS_GetCurrentContext(&AppDataPtr, &AppID); + if (Status == CFE_SUCCESS && EVS_AppDataIsMatch(AppDataPtr, AppID)) + { + EVS_AppDataSetFree(AppDataPtr); + } + + return (Status); + +} /* End CFE_EVS_Unregister */ + +/* +** Function: CFE_EVS_SendEvent - See API and header file for details +*/ +int32 CFE_EVS_SendEvent(uint16 EventID, uint16 EventType, const char *Spec, ...) +{ + int32 Status; + CFE_ES_AppId_t AppID; + CFE_TIME_SysTime_t Time; + va_list Ptr; + EVS_AppData_t * AppDataPtr; + + if (Spec == NULL) + { + return CFE_EVS_INVALID_PARAMETER; + } + + /* Query and verify the caller's AppID */ + Status = EVS_GetCurrentContext(&AppDataPtr, &AppID); + if (Status == CFE_SUCCESS) + { + if (!EVS_AppDataIsMatch(AppDataPtr, AppID)) + { + /* Handler for events from apps not registered with EVS */ + Status = EVS_NotRegistered(AppDataPtr, AppID); + } + else if (EVS_IsFiltered(AppDataPtr, EventID, EventType) == false) + { + /* Get current spacecraft time */ + Time = CFE_TIME_GetTime(); + + /* Send the event packets */ + va_start(Ptr, Spec); + EVS_GenerateEventTelemetry(AppDataPtr, EventID, EventType, &Time, Spec, Ptr); + va_end(Ptr); + } + } + + return (Status); + +} /* End CFE_EVS_SendEvent */ + +/* +** Function: CFE_EVS_SendEventWithAppID - See API and header file for details +*/ +int32 CFE_EVS_SendEventWithAppID(uint16 EventID, uint16 EventType, CFE_ES_AppId_t AppID, const char *Spec, ...) +{ + int32 Status = CFE_SUCCESS; + CFE_TIME_SysTime_t Time; + va_list Ptr; + EVS_AppData_t * AppDataPtr; + + if (Spec == NULL) + { + return CFE_EVS_INVALID_PARAMETER; + } + + AppDataPtr = EVS_GetAppDataByID(AppID); + if (AppDataPtr == NULL) + { + Status = CFE_EVS_APP_ILLEGAL_APP_ID; + } + else if (!EVS_AppDataIsMatch(AppDataPtr, AppID)) + { + /* Handler for events from apps not registered with EVS */ + Status = EVS_NotRegistered(AppDataPtr, AppID); + } + else if (EVS_IsFiltered(AppDataPtr, EventID, EventType) == false) + { + /* Get current spacecraft time */ + Time = CFE_TIME_GetTime(); + + /* Send the event packets */ + va_start(Ptr, Spec); + EVS_GenerateEventTelemetry(AppDataPtr, EventID, EventType, &Time, Spec, Ptr); + va_end(Ptr); + } + + return Status; + +} /* End CFE_EVS_SendEventWithAppID */ + +/* +** Function: CFE_EVS_SendTimedEvent - See API and header file for details +*/ +int32 CFE_EVS_SendTimedEvent(CFE_TIME_SysTime_t Time, uint16 EventID, uint16 EventType, const char *Spec, ...) +{ + int32 Status; + CFE_ES_AppId_t AppID; + va_list Ptr; + EVS_AppData_t *AppDataPtr; + + if (Spec == NULL) + { + return CFE_EVS_INVALID_PARAMETER; + } + + /* Query and verify the caller's AppID */ + Status = EVS_GetCurrentContext(&AppDataPtr, &AppID); + if (Status == CFE_SUCCESS) + { + if (!EVS_AppDataIsMatch(AppDataPtr, AppID)) + { + /* Handler for events from apps not registered with EVS */ + Status = EVS_NotRegistered(AppDataPtr, AppID); + } + else if (EVS_IsFiltered(AppDataPtr, EventID, EventType) == false) + { + /* Send the event packets */ + va_start(Ptr, Spec); + EVS_GenerateEventTelemetry(AppDataPtr, EventID, EventType, &Time, Spec, Ptr); + va_end(Ptr); + } + } + + return (Status); + +} /* End CFE_EVS_SendTimedEvent */ + +/* +** Function: CFE_EVS_ResetFilter - See API and header file for details +*/ +int32 CFE_EVS_ResetFilter(int16 EventID) +{ + int32 Status; + EVS_BinFilter_t *FilterPtr = NULL; + CFE_ES_AppId_t AppID; + EVS_AppData_t * AppDataPtr; + + /* Query and verify the caller's AppID */ + Status = EVS_GetCurrentContext(&AppDataPtr, &AppID); + if (Status == CFE_SUCCESS) + { + if (!EVS_AppDataIsMatch(AppDataPtr, AppID)) + { + Status = CFE_EVS_APP_NOT_REGISTERED; + } + else + { + FilterPtr = EVS_FindEventID(EventID, AppDataPtr->BinFilters); + + if (FilterPtr != NULL) + { + FilterPtr->Count = 0; + } + else + { + Status = CFE_EVS_EVT_NOT_REGISTERED; + } + } + } + + return (Status); + +} /* End CFE_EVS_ResetFilter */ + +/* +** Function: CFE_EVS_ResetAllFilters - See API and header file for details +*/ +int32 CFE_EVS_ResetAllFilters(void) +{ + int32 Status; + CFE_ES_AppId_t AppID; + uint32 i; + EVS_AppData_t *AppDataPtr; + + /* Query and verify the caller's AppID */ + Status = EVS_GetCurrentContext(&AppDataPtr, &AppID); + if (Status == CFE_SUCCESS) + { + if (!EVS_AppDataIsMatch(AppDataPtr, AppID)) + { + Status = CFE_EVS_APP_NOT_REGISTERED; + } + else + { + for (i = 0; i < CFE_PLATFORM_EVS_MAX_EVENT_FILTERS; i++) + { + AppDataPtr->BinFilters[i].Count = 0; + } + } + } + + return (Status); + +} /* End CFE_EVS_ResetAllFilters */ + +/* End CFE_EVS.C */ diff --git a/modules/evs/fsw/src/cfe_evs_log.c b/modules/evs/fsw/src/cfe_evs_log.c new file mode 100644 index 000000000..6fd1333b0 --- /dev/null +++ b/modules/evs/fsw/src/cfe_evs_log.c @@ -0,0 +1,284 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** File: cfe_evs_log.c +** +** Title: Event Services API - Log Control Interfaces +** +** Purpose: This module defines the top level functions of the +** Event Services Log control interfaces +** +*/ + +/* Include Files */ +#include "cfe_evs_module_all.h" /* All EVS internal definitions and API */ + +#include + +/* +** Function Prologue +** +** Function Name: EVS_AddLog +** +** Purpose: This routine adds an event packet to the internal event log. +** +** Assumptions and Notes: +** +*/ +void EVS_AddLog(CFE_EVS_LongEventTlm_t *EVS_PktPtr) +{ + + /* Serialize access to event log control variables */ + OS_MutSemTake(CFE_EVS_Global.EVS_SharedDataMutexID); + + if ((CFE_EVS_Global.EVS_LogPtr->LogFullFlag == true) && + (CFE_EVS_Global.EVS_LogPtr->LogMode == CFE_EVS_LogMode_DISCARD)) + { + /* If log is full and in discard mode, just count the event */ + CFE_EVS_Global.EVS_LogPtr->LogOverflowCounter++; + } + else + { + if (CFE_EVS_Global.EVS_LogPtr->LogFullFlag == true) + { + /* If log is full and in wrap mode, count it and store it */ + CFE_EVS_Global.EVS_LogPtr->LogOverflowCounter++; + } + + /* Copy the event data to the next available entry in the log */ + memcpy(&CFE_EVS_Global.EVS_LogPtr->LogEntry[CFE_EVS_Global.EVS_LogPtr->Next], EVS_PktPtr, sizeof(*EVS_PktPtr)); + + CFE_EVS_Global.EVS_LogPtr->Next++; + + if (CFE_EVS_Global.EVS_LogPtr->Next >= CFE_PLATFORM_EVS_LOG_MAX) + { + /* This is important, even if we are in discard mode */ + CFE_EVS_Global.EVS_LogPtr->Next = 0; + } + + /* Log count cannot exceed the number of entries in the log */ + if (CFE_EVS_Global.EVS_LogPtr->LogCount < CFE_PLATFORM_EVS_LOG_MAX) + { + CFE_EVS_Global.EVS_LogPtr->LogCount++; + + if (CFE_EVS_Global.EVS_LogPtr->LogCount == CFE_PLATFORM_EVS_LOG_MAX) + { + /* The full flag and log count are somewhat redundant */ + CFE_EVS_Global.EVS_LogPtr->LogFullFlag = true; + } + } + } + + OS_MutSemGive(CFE_EVS_Global.EVS_SharedDataMutexID); + + return; + +} /* End EVS_AddLog */ + +/* +** Function Prologue +** +** Function Name: EVS_ClearLog +** +** Purpose: This routine clears the contents of the internal event log. +** +** Assumptions and Notes: +** +*/ +void EVS_ClearLog(void) +{ + + /* Serialize access to event log control variables */ + OS_MutSemTake(CFE_EVS_Global.EVS_SharedDataMutexID); + + /* Clears everything but LogMode (overwrite vs discard) */ + CFE_EVS_Global.EVS_LogPtr->Next = 0; + CFE_EVS_Global.EVS_LogPtr->LogCount = 0; + CFE_EVS_Global.EVS_LogPtr->LogFullFlag = false; + CFE_EVS_Global.EVS_LogPtr->LogOverflowCounter = 0; + + memset(CFE_EVS_Global.EVS_LogPtr->LogEntry, 0, sizeof(CFE_EVS_Global.EVS_LogPtr->LogEntry)); + + OS_MutSemGive(CFE_EVS_Global.EVS_SharedDataMutexID); + + return; + +} /* End EVS_ClearLog */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_WriteLogDataFileCmd +** +** Purpose: This routine writes the contents of the internal event log to a file +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_WriteLogDataFileCmd(const CFE_EVS_WriteLogDataFileCmd_t *data) +{ + const CFE_EVS_LogFileCmd_Payload_t *CmdPtr = &data->Payload; + int32 Result; + int32 LogIndex; + int32 BytesWritten; + osal_id_t LogFileHandle = OS_OBJECT_ID_UNDEFINED; + uint32 i; + CFE_FS_Header_t LogFileHdr; + char LogFilename[OS_MAX_PATH_LEN]; + + /* + ** Copy the filename into local buffer with default name/path/extension if not specified + */ + Result = CFE_FS_ParseInputFileNameEx(LogFilename, CmdPtr->LogFilename, sizeof(LogFilename), + sizeof(CmdPtr->LogFilename), CFE_PLATFORM_EVS_DEFAULT_LOG_FILE, + CFE_FS_GetDefaultMountPoint(CFE_FS_FileCategory_BINARY_DATA_DUMP), + CFE_FS_GetDefaultExtension(CFE_FS_FileCategory_BINARY_DATA_DUMP)); + + if (Result != OS_SUCCESS) + { + EVS_SendEvent(CFE_EVS_ERR_CRLOGFILE_EID, CFE_EVS_EventType_ERROR, + "Write Log File Command Error: CFE_FS_ParseInputFileNameEx() = 0x%08X", (unsigned int)Result); + } + else + { + /* Create the log file */ + Result = OS_OpenCreate(&LogFileHandle, LogFilename, OS_FILE_FLAG_CREATE | OS_FILE_FLAG_TRUNCATE, OS_WRITE_ONLY); + if (Result != OS_SUCCESS) + { + EVS_SendEvent(CFE_EVS_ERR_CRLOGFILE_EID, CFE_EVS_EventType_ERROR, + "Write Log File Command Error: OS_OpenCreate = 0x%08X, filename = %s", (unsigned int)Result, + LogFilename); + } + } + + if (Result == OS_SUCCESS) + { + /* Result will be overridden if everything works */ + Result = CFE_EVS_FILE_WRITE_ERROR; + + /* Initialize cFE file header for an event log file */ + CFE_FS_InitHeader(&LogFileHdr, "cFE EVS Log File", CFE_FS_SubType_EVS_EVENTLOG); + + /* Write the file header to the log file */ + BytesWritten = CFE_FS_WriteHeader(LogFileHandle, &LogFileHdr); + + if (BytesWritten == sizeof(LogFileHdr)) + { + /* Serialize access to event log control variables */ + OS_MutSemTake(CFE_EVS_Global.EVS_SharedDataMutexID); + + /* Is the log full? -- Doesn't matter if wrap mode is enabled */ + if (CFE_EVS_Global.EVS_LogPtr->LogCount == CFE_PLATFORM_EVS_LOG_MAX) + { + /* Start with log entry that will be overwritten next (oldest) */ + LogIndex = CFE_EVS_Global.EVS_LogPtr->Next; + } + else + { + /* Start with the first entry in the log (oldest) */ + LogIndex = 0; + } + + /* Write all the "in-use" event log entries to the file */ + for (i = 0; i < CFE_EVS_Global.EVS_LogPtr->LogCount; i++) + { + BytesWritten = OS_write(LogFileHandle, &CFE_EVS_Global.EVS_LogPtr->LogEntry[LogIndex], + sizeof(CFE_EVS_Global.EVS_LogPtr->LogEntry[LogIndex])); + + if (BytesWritten == sizeof(CFE_EVS_Global.EVS_LogPtr->LogEntry[LogIndex])) + { + LogIndex++; + + if (LogIndex >= CFE_PLATFORM_EVS_LOG_MAX) + { + LogIndex = 0; + } + } + else + { + break; + } + } + + OS_MutSemGive(CFE_EVS_Global.EVS_SharedDataMutexID); + + /* Process command handler success result */ + if (i == CFE_EVS_Global.EVS_LogPtr->LogCount) + { + EVS_SendEvent(CFE_EVS_WRLOG_EID, CFE_EVS_EventType_DEBUG, + "Write Log File Command: %d event log entries written to %s", + (int)CFE_EVS_Global.EVS_LogPtr->LogCount, LogFilename); + Result = CFE_SUCCESS; + } + else + { + EVS_SendEvent(CFE_EVS_ERR_WRLOGFILE_EID, CFE_EVS_EventType_ERROR, + "Write Log File Command Error: OS_write = 0x%08X, filename = %s", + (unsigned int)BytesWritten, LogFilename); + } + } + + OS_close(LogFileHandle); + } + + return (Result); + +} /* End CFE_EVS_WriteLogDataFileCmd */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_SetLogModeCmd +** +** Purpose: This routine sets the internal event log mode. +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_SetLogModeCmd(const CFE_EVS_SetLogModeCmd_t *data) +{ + const CFE_EVS_SetLogMode_Payload_t *CmdPtr = &data->Payload; + int32 Status; + + if ((CmdPtr->LogMode == CFE_EVS_LogMode_OVERWRITE) || (CmdPtr->LogMode == CFE_EVS_LogMode_DISCARD)) + { + /* Serialize access to event log control variables */ + OS_MutSemTake(CFE_EVS_Global.EVS_SharedDataMutexID); + CFE_EVS_Global.EVS_LogPtr->LogMode = CmdPtr->LogMode; + OS_MutSemGive(CFE_EVS_Global.EVS_SharedDataMutexID); + + EVS_SendEvent(CFE_EVS_LOGMODE_EID, CFE_EVS_EventType_DEBUG, "Set Log Mode Command: Log Mode = %d", + (int)CmdPtr->LogMode); + + Status = CFE_SUCCESS; + } + else + { + Status = CFE_EVS_INVALID_PARAMETER; + EVS_SendEvent(CFE_EVS_ERR_LOGMODE_EID, CFE_EVS_EventType_ERROR, "Set Log Mode Command Error: Log Mode = %d", + (int)CmdPtr->LogMode); + } + + return Status; + +} /* End CFE_EVS_SetLogModeCmd */ + +/* END EVSLOG.C */ diff --git a/modules/evs/fsw/src/cfe_evs_log.h b/modules/evs/fsw/src/cfe_evs_log.h new file mode 100644 index 000000000..6ae064abe --- /dev/null +++ b/modules/evs/fsw/src/cfe_evs_log.h @@ -0,0 +1,60 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/** + * @file + * + * Title: Event Services API Log Control Interfaces. + * + * Purpose: + * Unit specification for the event services log control interfaces. + * + * Contents: + * I. macro and constant type definitions + * II. EVM internal structures + * III. function prototypes + * + * Design Notes: + * + * References: + * Flight Software Branch C Coding Standard Version 1.0a + * + * Notes: + */ + +#ifndef CFE_EVS_LOG_H +#define CFE_EVS_LOG_H + +/********************* Include Files ************************/ + +#include "cfe_evs_msg.h" /* EVS public definitions */ + +/* ============== Section I: Macro and Constant Type Definitions =========== */ + +/* ============== Section II: Internal Structures ============ */ + +/* ============== Section III: Function Prototypes =========== */ + +void EVS_AddLog(CFE_EVS_LongEventTlm_t *EVS_PktPtr); +void EVS_ClearLog(void); +int32 CFE_EVS_WriteLogDataFileCmd(const CFE_EVS_WriteLogDataFileCmd_t *data); +int32 CFE_EVS_SetLogModeCmd(const CFE_EVS_SetLogModeCmd_t *data); + +#endif /* CFE_EVS_LOG_H */ diff --git a/modules/evs/fsw/src/cfe_evs_module_all.h b/modules/evs/fsw/src/cfe_evs_module_all.h new file mode 100644 index 000000000..24550feaa --- /dev/null +++ b/modules/evs/fsw/src/cfe_evs_module_all.h @@ -0,0 +1,49 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/** + * @file + * + * Encapsulates all EVS module internal header files, as well + * as the public API from all other CFE core modules, OSAL, and PSP. + * + * This simplifies the set of include files that need to be put at the + * start of every source file. + */ + +#ifndef CFE_EVS_MODULE_ALL_H +#define CFE_EVS_MODULE_ALL_H + +/********************* Include Files ************************/ + +#include "cfe.h" /* All CFE+OSAL public API definitions */ +#include "cfe_platform_cfg.h" + +#include "cfe_msgids.h" +#include "cfe_perfids.h" + +#include "cfe_evs_core_internal.h" + +#include "cfe_evs_events.h" /* EVS event IDs */ +#include "cfe_evs_task.h" /* EVS internal definitions */ +#include "cfe_evs_log.h" /* EVS log file definitions */ +#include "cfe_evs_utils.h" /* EVS utility function definitions */ + +#endif /* CFE_EVS_MODULE_ALL_H */ diff --git a/modules/evs/fsw/src/cfe_evs_task.c b/modules/evs/fsw/src/cfe_evs_task.c new file mode 100644 index 000000000..20c816dd9 --- /dev/null +++ b/modules/evs/fsw/src/cfe_evs_task.c @@ -0,0 +1,1772 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** File: cfe_evs_task.c +** +** Title: Event Service API Management Control Interfaces +** +** Purpose: This module defines the top level functions of the +** cFE Event Service task defining the control, command, +** and telemetry interfaces +** +*/ + +/* Include Files */ +#include "cfe_evs_module_all.h" /* All EVS internal definitions and API */ +#include "cfe_version.h" /* cFE version definitions */ + +#include + +#include "cfe_es_resetdata_typedef.h" /* Definition of CFE_ES_ResetData_t */ + +/* Global Data */ +CFE_EVS_Global_t CFE_EVS_Global; + +/* Defines */ +#define CFE_EVS_PANIC_DELAY 500 /**< \brief Task delay before PSP panic */ + +/* +** Local function prototypes. +*/ +void CFE_EVS_ProcessGroundCommand(CFE_SB_Buffer_t *SBBufPtr, CFE_SB_MsgId_t MsgId); +bool CFE_EVS_VerifyCmdLength(CFE_MSG_Message_t *MsgPtr, size_t ExpectedLength); + +/* Function Definitions */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_EarlyInit +** +** Purpose: This routine provides initialization for the EVS API. +** +** Assumptions and Notes: This routine must be called before the EVS +** application is started. CFE_EVS_EarlyInit performs initialization +** necessary to support EVS API calls that might occur before +** the EVS application has completed its startup initialization. +*/ +int32 CFE_EVS_EarlyInit(void) +{ + + int32 Status; + uint32 resetAreaSize = 0; + cpuaddr resetAreaAddr; + CFE_ES_ResetData_t *CFE_EVS_ResetDataPtr = (CFE_ES_ResetData_t *)NULL; + + memset(&CFE_EVS_Global, 0, sizeof(CFE_EVS_Global)); + + /* Initialize housekeeping packet */ + CFE_MSG_Init(&CFE_EVS_Global.EVS_TlmPkt.TlmHeader.Msg, CFE_SB_ValueToMsgId(CFE_EVS_HK_TLM_MID), + sizeof(CFE_EVS_Global.EVS_TlmPkt)); + + /* Elements stored in the hk packet that have non-zero default values */ + CFE_EVS_Global.EVS_TlmPkt.Payload.MessageFormatMode = CFE_PLATFORM_EVS_DEFAULT_MSG_FORMAT_MODE; + CFE_EVS_Global.EVS_TlmPkt.Payload.OutputPort = CFE_PLATFORM_EVS_PORT_DEFAULT; + CFE_EVS_Global.EVS_TlmPkt.Payload.LogMode = CFE_PLATFORM_EVS_DEFAULT_LOG_MODE; + + /* Get a pointer to the CFE reset area from the BSP */ + Status = CFE_PSP_GetResetArea(&resetAreaAddr, &resetAreaSize); + + /* Panic on error */ + if (Status != CFE_PSP_SUCCESS) + { + /* Can't log evs messages without the reset area */ + CFE_ES_WriteToSysLog("EVS call to CFE_PSP_GetResetArea failed, RC=0x%08x\n", (unsigned int)Status); + + /* Delay to allow message to be read */ + OS_TaskDelay(CFE_EVS_PANIC_DELAY); + + CFE_PSP_Panic(CFE_PSP_PANIC_MEMORY_ALLOC); + } + else if (resetAreaSize < sizeof(CFE_ES_ResetData_t)) + { + /* Got the pointer but the size is wrong */ + Status = CFE_EVS_RESET_AREA_POINTER; + CFE_ES_WriteToSysLog("Unexpected size from CFE_PSP_GetResetArea: expected = 0x%08lX, actual = 0x%08lX\n", + (unsigned long)sizeof(CFE_ES_ResetData_t), (unsigned long)resetAreaSize); + + /* Delay to allow message to be read */ + OS_TaskDelay(CFE_EVS_PANIC_DELAY); + + CFE_PSP_Panic(CFE_PSP_PANIC_MEMORY_ALLOC); + } + else + { + CFE_EVS_ResetDataPtr = (CFE_ES_ResetData_t *)resetAreaAddr; + /* Save pointer to the EVS portion of the CFE reset area */ + CFE_EVS_Global.EVS_LogPtr = &CFE_EVS_ResetDataPtr->EVS_Log; + + /* Create semaphore to serialize access to event log */ + Status = OS_MutSemCreate(&CFE_EVS_Global.EVS_SharedDataMutexID, "CFE_EVS_DataMutex", 0); + + if (Status != OS_SUCCESS) + { + CFE_ES_WriteToSysLog("EVS call to OS_MutSemCreate failed, RC=0x%08x\n", (unsigned int)Status); + + /* Delay to allow message to be read */ + OS_TaskDelay(CFE_EVS_PANIC_DELAY); + + CFE_PSP_Panic(CFE_PSP_PANIC_STARTUP_SEM); + } + else + { + /* Convert to CFE success type */ + Status = CFE_SUCCESS; + } + + /* Report log as enabled */ + CFE_EVS_Global.EVS_TlmPkt.Payload.LogEnabled = true; + + /* Clear event log if power-on reset or bad contents */ + if (CFE_ES_GetResetType(NULL) == CFE_PSP_RST_TYPE_POWERON) + { + CFE_ES_WriteToSysLog("Event Log cleared following power-on reset\n"); + EVS_ClearLog(); + CFE_EVS_Global.EVS_LogPtr->LogMode = CFE_PLATFORM_EVS_DEFAULT_LOG_MODE; + } + else if (((CFE_EVS_Global.EVS_LogPtr->LogMode != CFE_EVS_LogMode_OVERWRITE) && + (CFE_EVS_Global.EVS_LogPtr->LogMode != CFE_EVS_LogMode_DISCARD)) || + ((CFE_EVS_Global.EVS_LogPtr->LogFullFlag != false) && + (CFE_EVS_Global.EVS_LogPtr->LogFullFlag != true)) || + (CFE_EVS_Global.EVS_LogPtr->Next >= CFE_PLATFORM_EVS_LOG_MAX)) + { + CFE_ES_WriteToSysLog("Event Log cleared, n=%d, c=%d, f=%d, m=%d, o=%d\n", + (int)CFE_EVS_Global.EVS_LogPtr->Next, (int)CFE_EVS_Global.EVS_LogPtr->LogCount, + (int)CFE_EVS_Global.EVS_LogPtr->LogFullFlag, (int)CFE_EVS_Global.EVS_LogPtr->LogMode, + (int)CFE_EVS_Global.EVS_LogPtr->LogOverflowCounter); + EVS_ClearLog(); + CFE_EVS_Global.EVS_LogPtr->LogMode = CFE_PLATFORM_EVS_DEFAULT_LOG_MODE; + } + else + { + CFE_ES_WriteToSysLog("Event Log restored, n=%d, c=%d, f=%d, m=%d, o=%d\n", + (int)CFE_EVS_Global.EVS_LogPtr->Next, (int)CFE_EVS_Global.EVS_LogPtr->LogCount, + (int)CFE_EVS_Global.EVS_LogPtr->LogFullFlag, (int)CFE_EVS_Global.EVS_LogPtr->LogMode, + (int)CFE_EVS_Global.EVS_LogPtr->LogOverflowCounter); + } + } + + return (Status); + +} /* End CFE_EVS_EarlyInit */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_CleanUpApp +** +** Purpose: ES calls this routine when an app is being terminated. +** +** Assumptions and Notes: +*/ +int32 CFE_EVS_CleanUpApp(CFE_ES_AppId_t AppID) +{ + int32 Status = CFE_SUCCESS; + EVS_AppData_t *AppDataPtr; + + /* Query and verify the caller's AppID */ + AppDataPtr = EVS_GetAppDataByID(AppID); + if (AppDataPtr == NULL) + { + Status = CFE_EVS_APP_ILLEGAL_APP_ID; + } + else if (EVS_AppDataIsMatch(AppDataPtr, AppID)) + { + /* Same cleanup as CFE_EVS_Unregister() */ + EVS_AppDataSetFree(AppDataPtr); + } + + return (Status); +} + +/* +** Function Prologue +** +** Function Name: EVS_TaskMain +** +** Purpose: This is the main EVS task process loop. +** +** Assumptions and Notes: +** +*/ +void CFE_EVS_TaskMain(void) +{ + int32 Status; + CFE_SB_Buffer_t *SBBufPtr; + + CFE_ES_PerfLogEntry(CFE_MISSION_EVS_MAIN_PERF_ID); + + Status = CFE_EVS_TaskInit(); + + if (Status != CFE_SUCCESS) + { + CFE_ES_WriteToSysLog("EVS:Application Init Failed,RC=0x%08X\n", (unsigned int)Status); + CFE_ES_PerfLogExit(CFE_MISSION_EVS_MAIN_PERF_ID); + /* Note: CFE_ES_ExitApp will not return */ + CFE_ES_ExitApp(CFE_ES_RunStatus_CORE_APP_INIT_ERROR); + } /* end if */ + + /* + * Wait for other apps to start. + * It is important that the core apps are present before this starts receiving + * messages from the command pipe, as some of those handlers might depend on + * the other core apps. + */ + CFE_ES_WaitForSystemState(CFE_ES_SystemState_CORE_READY, CFE_PLATFORM_CORE_MAX_STARTUP_MSEC); + + /* Main loop */ + while (Status == CFE_SUCCESS) + { + /* Increment the Main task Execution Counter */ + CFE_ES_IncrementTaskCounter(); + + CFE_ES_PerfLogExit(CFE_MISSION_EVS_MAIN_PERF_ID); + + /* Pend on receipt of packet */ + Status = CFE_SB_ReceiveBuffer(&SBBufPtr, CFE_EVS_Global.EVS_CommandPipe, CFE_SB_PEND_FOREVER); + + CFE_ES_PerfLogEntry(CFE_MISSION_EVS_MAIN_PERF_ID); + + if (Status == CFE_SUCCESS) + { + /* Process cmd pipe msg */ + CFE_EVS_ProcessCommandPacket(SBBufPtr); + } + else + { + CFE_ES_WriteToSysLog("EVS:Error reading cmd pipe,RC=0x%08X\n", (unsigned int)Status); + } /* end if */ + + } /* end while */ + + /* while loop exits only if CFE_SB_ReceiveBuffer returns error */ + CFE_ES_ExitApp(CFE_ES_RunStatus_CORE_APP_RUNTIME_ERROR); + +} /* end CFE_EVS_TaskMain */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_TaskInit +** +** Purpose: This function performs any necessary EVS task initialization. +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_TaskInit(void) +{ + int32 Status; + CFE_ES_AppId_t AppID; + + /* Query and verify the AppID */ + Status = CFE_ES_GetAppID(&AppID); + if (Status != CFE_SUCCESS) + { + CFE_ES_WriteToSysLog("EVS:Call to CFE_ES_GetAppID Failed:RC=0x%08X\n", (unsigned int)Status); + return Status; + } + + /* Register EVS task for event services */ + Status = CFE_EVS_Register(NULL, 0, CFE_EVS_EventFilter_BINARY); + if (Status != CFE_SUCCESS) + { + CFE_ES_WriteToSysLog("EVS:Call to CFE_EVS_Register Failed:RC=0x%08X\n", (unsigned int)Status); + return Status; + } + + /* Create software bus command pipe */ + Status = CFE_SB_CreatePipe(&CFE_EVS_Global.EVS_CommandPipe, CFE_EVS_PIPE_DEPTH, CFE_EVS_PIPE_NAME); + if (Status != CFE_SUCCESS) + { + CFE_ES_WriteToSysLog("EVS:Call to CFE_SB_CreatePipe Failed:RC=0x%08X\n", (unsigned int)Status); + return Status; + } + + /* Subscribe to command and telemetry requests coming in on the command pipe */ + Status = CFE_SB_Subscribe(CFE_SB_ValueToMsgId(CFE_EVS_CMD_MID), CFE_EVS_Global.EVS_CommandPipe); + if (Status != CFE_SUCCESS) + { + CFE_ES_WriteToSysLog("EVS:Subscribing to Cmds Failed:RC=0x%08X\n", (unsigned int)Status); + return Status; + } + + Status = CFE_SB_Subscribe(CFE_SB_ValueToMsgId(CFE_EVS_SEND_HK_MID), CFE_EVS_Global.EVS_CommandPipe); + if (Status != CFE_SUCCESS) + { + CFE_ES_WriteToSysLog("EVS:Subscribing to HK Request Failed:RC=0x%08X\n", (unsigned int)Status); + return Status; + } + + /* Write the AppID to the global location, now that the rest of initialization is done */ + CFE_EVS_Global.EVS_AppID = AppID; + EVS_SendEvent(CFE_EVS_STARTUP_EID, CFE_EVS_EventType_INFORMATION, "cFE EVS Initialized.%s", CFE_VERSION_STRING); + + return CFE_SUCCESS; + +} /* End CFE_EVS_TaskInit */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_ProcessCommandPacket +** +** Purpose: This function processes packets received on the EVS command pipe. +** +** Assumptions and Notes: +** +*/ +void CFE_EVS_ProcessCommandPacket(CFE_SB_Buffer_t *SBBufPtr) +{ + CFE_SB_MsgId_t MessageID = CFE_SB_INVALID_MSG_ID; + + CFE_MSG_GetMsgId(&SBBufPtr->Msg, &MessageID); + + /* Process all SB messages */ + switch (CFE_SB_MsgIdToValue(MessageID)) + { + case CFE_EVS_CMD_MID: + /* EVS task specific command */ + CFE_EVS_ProcessGroundCommand(SBBufPtr, MessageID); + break; + + case CFE_EVS_SEND_HK_MID: + /* Housekeeping request */ + CFE_EVS_ReportHousekeepingCmd((CFE_MSG_CommandHeader_t *)SBBufPtr); + break; + + default: + /* Unknown command -- should never occur */ + CFE_EVS_Global.EVS_TlmPkt.Payload.CommandErrorCounter++; + EVS_SendEvent(CFE_EVS_ERR_MSGID_EID, CFE_EVS_EventType_ERROR, "Invalid command packet, Message ID = 0x%08X", + (unsigned int)CFE_SB_MsgIdToValue(MessageID)); + break; + } + + return; + +} /* End CFE_EVS_ProcessCommandPacket */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_ProcessGroundCommand +** +** Purpose: This function processes a command, verifying that it is valid and of +** proper length. +** +** Assumptions and Notes: +** +*/ +void CFE_EVS_ProcessGroundCommand(CFE_SB_Buffer_t *SBBufPtr, CFE_SB_MsgId_t MsgId) +{ + /* status will get reset if it passes length check */ + int32 Status = CFE_STATUS_WRONG_MSG_LENGTH; + CFE_MSG_FcnCode_t FcnCode = 0; + + CFE_MSG_GetFcnCode(&SBBufPtr->Msg, &FcnCode); + + /* Process "known" EVS task ground commands */ + switch (FcnCode) + { + case CFE_EVS_NOOP_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_NoopCmd_t))) + { + Status = CFE_EVS_NoopCmd((CFE_EVS_NoopCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_RESET_COUNTERS_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_ResetCountersCmd_t))) + { + Status = CFE_EVS_ResetCountersCmd((CFE_EVS_ResetCountersCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_ENABLE_EVENT_TYPE_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_EnableEventTypeCmd_t))) + { + Status = CFE_EVS_EnableEventTypeCmd((CFE_EVS_EnableEventTypeCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_DISABLE_EVENT_TYPE_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_DisableEventTypeCmd_t))) + { + Status = CFE_EVS_DisableEventTypeCmd((CFE_EVS_DisableEventTypeCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_SET_EVENT_FORMAT_MODE_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_SetEventFormatModeCmd_t))) + { + Status = CFE_EVS_SetEventFormatModeCmd((CFE_EVS_SetEventFormatModeCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_ENABLE_APP_EVENT_TYPE_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_EnableAppEventTypeCmd_t))) + { + Status = CFE_EVS_EnableAppEventTypeCmd((CFE_EVS_EnableAppEventTypeCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_DISABLE_APP_EVENT_TYPE_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_DisableAppEventTypeCmd_t))) + { + Status = CFE_EVS_DisableAppEventTypeCmd((CFE_EVS_DisableAppEventTypeCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_ENABLE_APP_EVENTS_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_EnableAppEventsCmd_t))) + { + Status = CFE_EVS_EnableAppEventsCmd((CFE_EVS_EnableAppEventsCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_DISABLE_APP_EVENTS_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_DisableAppEventsCmd_t))) + { + Status = CFE_EVS_DisableAppEventsCmd((CFE_EVS_DisableAppEventsCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_RESET_APP_COUNTER_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_ResetAppCounterCmd_t))) + { + Status = CFE_EVS_ResetAppCounterCmd((CFE_EVS_ResetAppCounterCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_SET_FILTER_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_SetFilterCmd_t))) + { + Status = CFE_EVS_SetFilterCmd((CFE_EVS_SetFilterCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_ENABLE_PORTS_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_EnablePortsCmd_t))) + { + Status = CFE_EVS_EnablePortsCmd((CFE_EVS_EnablePortsCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_DISABLE_PORTS_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_DisablePortsCmd_t))) + { + Status = CFE_EVS_DisablePortsCmd((CFE_EVS_DisablePortsCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_RESET_FILTER_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_ResetFilterCmd_t))) + { + Status = CFE_EVS_ResetFilterCmd((CFE_EVS_ResetFilterCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_RESET_ALL_FILTERS_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_ResetAllFiltersCmd_t))) + { + Status = CFE_EVS_ResetAllFiltersCmd((CFE_EVS_ResetAllFiltersCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_ADD_EVENT_FILTER_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_AddEventFilterCmd_t))) + { + Status = CFE_EVS_AddEventFilterCmd((CFE_EVS_AddEventFilterCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_DELETE_EVENT_FILTER_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_DeleteEventFilterCmd_t))) + { + Status = CFE_EVS_DeleteEventFilterCmd((CFE_EVS_DeleteEventFilterCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_WRITE_APP_DATA_FILE_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_WriteAppDataFileCmd_t))) + { + Status = CFE_EVS_WriteAppDataFileCmd((CFE_EVS_WriteAppDataFileCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_SET_LOG_MODE_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_SetLogModeCmd_t))) + { + Status = CFE_EVS_SetLogModeCmd((CFE_EVS_SetLogModeCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_CLEAR_LOG_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_ClearLogCmd_t))) + { + Status = CFE_EVS_ClearLogCmd((CFE_EVS_ClearLogCmd_t *)SBBufPtr); + } + break; + + case CFE_EVS_WRITE_LOG_DATA_FILE_CC: + + if (CFE_EVS_VerifyCmdLength(&SBBufPtr->Msg, sizeof(CFE_EVS_WriteLogDataFileCmd_t))) + { + Status = CFE_EVS_WriteLogDataFileCmd((CFE_EVS_WriteLogDataFileCmd_t *)SBBufPtr); + } + break; + + /* default is a bad command code as it was not found above */ + default: + + EVS_SendEvent(CFE_EVS_ERR_CC_EID, CFE_EVS_EventType_ERROR, "Invalid command code -- ID = 0x%08x, CC = %u", + (unsigned int)CFE_SB_MsgIdToValue(MsgId), (unsigned int)FcnCode); + Status = CFE_STATUS_BAD_COMMAND_CODE; + + break; + } + + if (Status == CFE_SUCCESS) + { + CFE_EVS_Global.EVS_TlmPkt.Payload.CommandCounter++; + } + else if (Status < 0) /* Negative values indicate errors */ + { + CFE_EVS_Global.EVS_TlmPkt.Payload.CommandErrorCounter++; + } + + return; + +} /* End of EVS_ProcessGroundCommand() */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_VerifyCmdLength +** +** Purpose: This function validates the length of incoming commands. +** +** Assumptions and Notes: +** +*/ +bool CFE_EVS_VerifyCmdLength(CFE_MSG_Message_t *MsgPtr, size_t ExpectedLength) +{ + bool result = true; + CFE_MSG_Size_t ActualLength = 0; + CFE_MSG_FcnCode_t FcnCode = 0; + CFE_SB_MsgId_t MsgId = CFE_SB_INVALID_MSG_ID; + + CFE_MSG_GetSize(MsgPtr, &ActualLength); + + /* + ** Verify the command packet length + */ + if (ExpectedLength != ActualLength) + { + CFE_MSG_GetMsgId(MsgPtr, &MsgId); + CFE_MSG_GetFcnCode(MsgPtr, &FcnCode); + + EVS_SendEvent(CFE_EVS_LEN_ERR_EID, CFE_EVS_EventType_ERROR, + "Invalid msg length: ID = 0x%X, CC = %u, Len = %u, Expected = %u", + (unsigned int)CFE_SB_MsgIdToValue(MsgId), (unsigned int)FcnCode, (unsigned int)ActualLength, + (unsigned int)ExpectedLength); + result = false; + } + + return (result); + +} /* End of CFE_EVS_VerifyCmdLength() */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_NoopCmd +** +** Purpose: This function processes "no-op" commands received on the EVS command pipe. +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_NoopCmd(const CFE_EVS_NoopCmd_t *data) +{ + EVS_SendEvent(CFE_EVS_NOOP_EID, CFE_EVS_EventType_INFORMATION, "No-op command. %s", CFE_VERSION_STRING); + return CFE_SUCCESS; +} + +/* +** Function Prologue +** +** Function Name: CFE_EVS_ClearLogCmd +** +** Purpose: This function processes "clear log" commands received on the EVS command pipe. +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_ClearLogCmd(const CFE_EVS_ClearLogCmd_t *data) +{ + EVS_ClearLog(); + return CFE_SUCCESS; +} + +/* +** Function Prologue +** +** Function Name: CFE_EVS_ReportHousekeepingCmd +** +** Purpose: Request for housekeeping status telemetry packet. +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_ReportHousekeepingCmd(const CFE_MSG_CommandHeader_t *data) +{ + uint32 i, j; + EVS_AppData_t * AppDataPtr; + CFE_EVS_AppTlmData_t *AppTlmDataPtr; + + /* Copy hk variables that are maintained in the event log */ + CFE_EVS_Global.EVS_TlmPkt.Payload.LogFullFlag = CFE_EVS_Global.EVS_LogPtr->LogFullFlag; + CFE_EVS_Global.EVS_TlmPkt.Payload.LogMode = CFE_EVS_Global.EVS_LogPtr->LogMode; + CFE_EVS_Global.EVS_TlmPkt.Payload.LogOverflowCounter = CFE_EVS_Global.EVS_LogPtr->LogOverflowCounter; + + /* Write event state data for registered apps to telemetry packet */ + AppDataPtr = CFE_EVS_Global.AppData; + AppTlmDataPtr = CFE_EVS_Global.EVS_TlmPkt.Payload.AppData; + for (i = 0, j = 0; j < CFE_MISSION_ES_MAX_APPLICATIONS && i < CFE_PLATFORM_ES_MAX_APPLICATIONS; i++) + { + if (EVS_AppDataIsUsed(AppDataPtr)) + { + AppTlmDataPtr->AppID = EVS_AppDataGetID(AppDataPtr); + AppTlmDataPtr->AppEnableStatus = AppDataPtr->ActiveFlag; + AppTlmDataPtr->AppMessageSentCounter = AppDataPtr->EventCount; + ++j; + ++AppTlmDataPtr; + } + ++AppDataPtr; + } + + /* Clear unused portion of event state data in telemetry packet */ + for (i = j; i < CFE_MISSION_ES_MAX_APPLICATIONS; i++) + { + AppTlmDataPtr->AppID = CFE_ES_APPID_UNDEFINED; + AppTlmDataPtr->AppEnableStatus = false; + AppTlmDataPtr->AppMessageSentCounter = 0; + } + + CFE_SB_TimeStampMsg(&CFE_EVS_Global.EVS_TlmPkt.TlmHeader.Msg); + + CFE_SB_TransmitMsg(&CFE_EVS_Global.EVS_TlmPkt.TlmHeader.Msg, true); + + return CFE_STATUS_NO_COUNTER_INCREMENT; +} /* End of CFE_EVS_ReportHousekeepingCmd() */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_ResetCountersCmd +** +** Purpose: This function resets all the global counter variables that are +** part of the task telemetry. +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_ResetCountersCmd(const CFE_EVS_ResetCountersCmd_t *data) +{ + /* Status of commands processed by EVS task */ + CFE_EVS_Global.EVS_TlmPkt.Payload.CommandCounter = 0; + CFE_EVS_Global.EVS_TlmPkt.Payload.CommandErrorCounter = 0; + + /* EVS telemetry counters */ + CFE_EVS_Global.EVS_TlmPkt.Payload.MessageSendCounter = 0; + CFE_EVS_Global.EVS_TlmPkt.Payload.MessageTruncCounter = 0; + CFE_EVS_Global.EVS_TlmPkt.Payload.UnregisteredAppCounter = 0; + + EVS_SendEvent(CFE_EVS_RSTCNT_EID, CFE_EVS_EventType_DEBUG, "Reset Counters Command Received"); + + /* NOTE: Historically the reset counters command does _NOT_ increment the command counter */ + + return CFE_STATUS_NO_COUNTER_INCREMENT; +} /* End of CFE_EVS_ResetCountersCmd() */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_SetEventFilterMaskCmd +** +** Purpose: This routine sets the filter mask for the given event_id in the +** calling task's filter array +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_SetFilterCmd(const CFE_EVS_SetFilterCmd_t *data) +{ + const CFE_EVS_AppNameEventIDMaskCmd_Payload_t *CmdPtr = &data->Payload; + EVS_BinFilter_t * FilterPtr; + int32 Status; + EVS_AppData_t * AppDataPtr; + char LocalName[OS_MAX_API_NAME]; + + /* + * Althgouh EVS_GetApplicationInfo() does not require a null terminated argument, + * the value is passed to EVS_SendEvent which does require termination (normal C string) + */ + CFE_SB_MessageStringGet(LocalName, (char *)CmdPtr->AppName, NULL, sizeof(LocalName), sizeof(CmdPtr->AppName)); + + /* Retreive application data */ + Status = EVS_GetApplicationInfo(&AppDataPtr, LocalName); + + if (Status == CFE_SUCCESS) + { + FilterPtr = EVS_FindEventID(CmdPtr->EventID, AppDataPtr->BinFilters); + + if (FilterPtr != NULL) + { + /* Set application filter mask */ + FilterPtr->Mask = CmdPtr->Mask; + + EVS_SendEvent(CFE_EVS_SETFILTERMSK_EID, CFE_EVS_EventType_DEBUG, + "Set Filter Mask Command Received with AppName=%s, EventID=0x%08x, Mask=0x%04x", LocalName, + (unsigned int)CmdPtr->EventID, (unsigned int)CmdPtr->Mask); + } + else + { + EVS_SendEvent(CFE_EVS_ERR_EVTIDNOREGS_EID, CFE_EVS_EventType_ERROR, + "%s Event ID %d not registered for filtering: CC = %lu ", LocalName, (int)CmdPtr->EventID, + (long unsigned int)CFE_EVS_SET_FILTER_CC); + + Status = CFE_EVS_EVT_NOT_REGISTERED; + } + } + else if (Status == CFE_EVS_APP_NOT_REGISTERED) + { + EVS_SendEvent(CFE_EVS_ERR_APPNOREGS_EID, CFE_EVS_EventType_ERROR, "%s not registered with EVS: CC = %lu", + LocalName, (long unsigned int)CFE_EVS_SET_FILTER_CC); + } + else if (Status == CFE_EVS_APP_ILLEGAL_APP_ID) + { + EVS_SendEvent(CFE_EVS_ERR_ILLAPPIDRANGE_EID, CFE_EVS_EventType_ERROR, + "Illegal application ID retrieved for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_SET_FILTER_CC); + } + else + { + EVS_SendEvent(CFE_EVS_ERR_NOAPPIDFOUND_EID, CFE_EVS_EventType_ERROR, + "Unable to retrieve application ID for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_SET_FILTER_CC); + } + + return Status; + +} /* End CFE_EVS_SetFilterMaskCmd */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_EnablePortsCmd +** +** Purpose: This routine sets the command given ports to an enabled state +** +** Assumptions and Notes: +** Shifting is done so the value not masked off is placed in the ones spot: +** necessary for comparing with true. +*/ +int32 CFE_EVS_EnablePortsCmd(const CFE_EVS_EnablePortsCmd_t *data) +{ + const CFE_EVS_BitMaskCmd_Payload_t *CmdPtr = &data->Payload; + int32 ReturnCode; + + /* Need to check for an out of range bitmask, since oue bit masks are only 4 bits */ + if (CmdPtr->BitMask == 0x0 || CmdPtr->BitMask > 0x0F) + { + EVS_SendEvent(CFE_EVS_ERR_INVALID_BITMASK_EID, CFE_EVS_EventType_ERROR, + "Bit Mask = 0x%08x out of range: CC = %lu", (unsigned int)CmdPtr->BitMask, + (long unsigned int)CFE_EVS_ENABLE_PORTS_CC); + ReturnCode = CFE_EVS_INVALID_PARAMETER; + } + else + { + + /* Process command data */ + if (((CmdPtr->BitMask & CFE_EVS_PORT1_BIT) >> 0) == true) + { + CFE_EVS_Global.EVS_TlmPkt.Payload.OutputPort |= CFE_EVS_PORT1_BIT; + } + if (((CmdPtr->BitMask & CFE_EVS_PORT2_BIT) >> 1) == true) + { + CFE_EVS_Global.EVS_TlmPkt.Payload.OutputPort |= CFE_EVS_PORT2_BIT; + } + if (((CmdPtr->BitMask & CFE_EVS_PORT3_BIT) >> 2) == true) + { + CFE_EVS_Global.EVS_TlmPkt.Payload.OutputPort |= CFE_EVS_PORT3_BIT; + } + if (((CmdPtr->BitMask & CFE_EVS_PORT4_BIT) >> 3) == true) + { + CFE_EVS_Global.EVS_TlmPkt.Payload.OutputPort |= CFE_EVS_PORT4_BIT; + } + + EVS_SendEvent(CFE_EVS_ENAPORT_EID, CFE_EVS_EventType_DEBUG, + "Enable Ports Command Received with Port Bit Mask = 0x%02x", (unsigned int)CmdPtr->BitMask); + ReturnCode = CFE_SUCCESS; + } + + return ReturnCode; + +} /* End CFE_EVS_EnablePortsCmd */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_DisablePortsCmd +** +** Purpose: This routine sets the command given ports to a disabled state +** +** Assumptions and Notes: +** Shifting is done so the value not masked off is placed in the ones spot: +** necessary for comparing with true. +*/ +int32 CFE_EVS_DisablePortsCmd(const CFE_EVS_DisablePortsCmd_t *data) +{ + const CFE_EVS_BitMaskCmd_Payload_t *CmdPtr = &data->Payload; + int32 ReturnCode; + + /* Need to check for an out of range bitmask, since oue bit masks are only 4 bits */ + if (CmdPtr->BitMask == 0x0 || CmdPtr->BitMask > 0x0F) + { + EVS_SendEvent(CFE_EVS_ERR_INVALID_BITMASK_EID, CFE_EVS_EventType_ERROR, + "Bit Mask = 0x%08x out of range: CC = %lu", (unsigned int)CmdPtr->BitMask, + (long unsigned int)CFE_EVS_DISABLE_PORTS_CC); + ReturnCode = CFE_EVS_INVALID_PARAMETER; + } + else + { + + /* Process command data */ + if (((CmdPtr->BitMask & CFE_EVS_PORT1_BIT) >> 0) == true) + { + CFE_EVS_Global.EVS_TlmPkt.Payload.OutputPort &= ~CFE_EVS_PORT1_BIT; + } + if (((CmdPtr->BitMask & CFE_EVS_PORT2_BIT) >> 1) == true) + { + CFE_EVS_Global.EVS_TlmPkt.Payload.OutputPort &= ~CFE_EVS_PORT2_BIT; + } + if (((CmdPtr->BitMask & CFE_EVS_PORT3_BIT) >> 2) == true) + { + CFE_EVS_Global.EVS_TlmPkt.Payload.OutputPort &= ~CFE_EVS_PORT3_BIT; + } + if (((CmdPtr->BitMask & CFE_EVS_PORT4_BIT) >> 3) == true) + { + CFE_EVS_Global.EVS_TlmPkt.Payload.OutputPort &= ~CFE_EVS_PORT4_BIT; + } + + EVS_SendEvent(CFE_EVS_DISPORT_EID, CFE_EVS_EventType_DEBUG, + "Disable Ports Command Received with Port Bit Mask = 0x%02x", (unsigned int)CmdPtr->BitMask); + + ReturnCode = CFE_SUCCESS; + } + + return ReturnCode; + +} /* End CFE_EVS_DisablePortsCmd */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_EnableEventTypesCmd +** +** Purpose: This routine sets the given event types to an enabled state across all +** registered applications +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_EnableEventTypeCmd(const CFE_EVS_EnableEventTypeCmd_t *data) +{ + uint32 i; + const CFE_EVS_BitMaskCmd_Payload_t *CmdPtr = &data->Payload; + int32 ReturnCode; + EVS_AppData_t * AppDataPtr; + + /* Need to check for an out of range bitmask, since our bit masks are only 4 bits */ + if (CmdPtr->BitMask == 0x0 || CmdPtr->BitMask > 0x0F) + { + EVS_SendEvent(CFE_EVS_ERR_INVALID_BITMASK_EID, CFE_EVS_EventType_ERROR, + "Bit Mask = 0x%08x out of range: CC = %lu", (unsigned int)CmdPtr->BitMask, + (long unsigned int)CFE_EVS_ENABLE_EVENT_TYPE_CC); + ReturnCode = CFE_EVS_INVALID_PARAMETER; + } + else + { + AppDataPtr = CFE_EVS_Global.AppData; + for (i = 0; i < CFE_PLATFORM_ES_MAX_APPLICATIONS; i++) + { + /* Make sure application is registered for event services */ + if (EVS_AppDataIsUsed(AppDataPtr)) + { + EVS_EnableTypes(AppDataPtr, CmdPtr->BitMask); + } + ++AppDataPtr; + } + + EVS_SendEvent(CFE_EVS_ENAEVTTYPE_EID, CFE_EVS_EventType_DEBUG, + "Enable Event Type Command Received with Event Type Bit Mask = 0x%02x", + (unsigned int)CmdPtr->BitMask); + + ReturnCode = CFE_SUCCESS; + } + + return ReturnCode; + +} /* End CFE_EVS_EnableEventTypesCmd */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_DisableEventTypesCmd +** +** Purpose: This routine sets the given event types to a disabled state across all +** registered applications +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_DisableEventTypeCmd(const CFE_EVS_DisableEventTypeCmd_t *data) +{ + uint32 i; + const CFE_EVS_BitMaskCmd_Payload_t *CmdPtr = &data->Payload; + int32 ReturnCode; + EVS_AppData_t * AppDataPtr; + + /* Need to check for an out of range bitmask, since our bit masks are only 4 bits */ + if (CmdPtr->BitMask == 0x0 || CmdPtr->BitMask > 0x0F) + { + EVS_SendEvent(CFE_EVS_ERR_INVALID_BITMASK_EID, CFE_EVS_EventType_ERROR, + "Bit Mask = 0x%08x out of range: CC = %lu", (unsigned int)CmdPtr->BitMask, + (long unsigned int)CFE_EVS_DISABLE_EVENT_TYPE_CC); + ReturnCode = CFE_EVS_INVALID_PARAMETER; + } + + else + { + AppDataPtr = CFE_EVS_Global.AppData; + for (i = 0; i < CFE_PLATFORM_ES_MAX_APPLICATIONS; i++) + { + /* Make sure application is registered for event services */ + if (EVS_AppDataIsUsed(AppDataPtr)) + { + EVS_DisableTypes(AppDataPtr, CmdPtr->BitMask); + } + ++AppDataPtr; + } + + EVS_SendEvent(CFE_EVS_DISEVTTYPE_EID, CFE_EVS_EventType_DEBUG, + "Disable Event Type Command Received with Event Type Bit Mask = 0x%02x", + (unsigned int)CmdPtr->BitMask); + + ReturnCode = CFE_SUCCESS; + } + + return ReturnCode; + +} /* End CFE_EVS_DisableEventTypesCmd */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_SetEventFormatModeCmd +** +** Purpose: This routine sets the Event Format Mode +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_SetEventFormatModeCmd(const CFE_EVS_SetEventFormatModeCmd_t *data) +{ + const CFE_EVS_SetEventFormatMode_Payload_t *CmdPtr = &data->Payload; + int32 Status; + + if ((CmdPtr->MsgFormat == CFE_EVS_MsgFormat_SHORT) || (CmdPtr->MsgFormat == CFE_EVS_MsgFormat_LONG)) + { + CFE_EVS_Global.EVS_TlmPkt.Payload.MessageFormatMode = CmdPtr->MsgFormat; + + EVS_SendEvent(CFE_EVS_SETEVTFMTMOD_EID, CFE_EVS_EventType_DEBUG, + "Set Event Format Mode Command Received with Mode = 0x%02x", (unsigned int)CmdPtr->MsgFormat); + Status = CFE_SUCCESS; + } + else + { + EVS_SendEvent(CFE_EVS_ERR_ILLEGALFMTMOD_EID, CFE_EVS_EventType_ERROR, + "Set Event Format Mode Command: Invalid Event Format Mode = 0x%02x", + (unsigned int)CmdPtr->MsgFormat); + Status = CFE_EVS_INVALID_PARAMETER; + } + + return Status; + +} /* End CFE_EVS_SetEventFormatModeCmd */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_EnableAppEventTypesCmd +** +** Purpose: This routine sets the given event type for the given application identifier to an +** enabled state +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_EnableAppEventTypeCmd(const CFE_EVS_EnableAppEventTypeCmd_t *data) +{ + const CFE_EVS_AppNameBitMaskCmd_Payload_t *CmdPtr = &data->Payload; + EVS_AppData_t * AppDataPtr; + int32 Status; + char LocalName[OS_MAX_API_NAME]; + + /* + * Althgouh EVS_GetApplicationInfo() does not require a null terminated argument, + * the value is passed to EVS_SendEvent which does require termination (normal C string) + */ + CFE_SB_MessageStringGet(LocalName, (char *)CmdPtr->AppName, NULL, sizeof(LocalName), sizeof(CmdPtr->AppName)); + + /* Retrieve application data */ + Status = EVS_GetApplicationInfo(&AppDataPtr, LocalName); + + if (Status == CFE_SUCCESS) + { + + /* Need to check for an out of range bitmask, since our bit masks are only 4 bits */ + if (CmdPtr->BitMask == 0x0 || CmdPtr->BitMask > 0x0F) + { + EVS_SendEvent(CFE_EVS_ERR_INVALID_BITMASK_EID, CFE_EVS_EventType_ERROR, + "Bit Mask = 0x%08x out of range: CC = %lu", (unsigned int)CmdPtr->BitMask, + (long unsigned int)CFE_EVS_ENABLE_APP_EVENT_TYPE_CC); + Status = CFE_EVS_INVALID_PARAMETER; + } + else + { + EVS_EnableTypes(AppDataPtr, CmdPtr->BitMask); + } + } + else if (Status == CFE_EVS_APP_NOT_REGISTERED) + { + EVS_SendEvent(CFE_EVS_ERR_APPNOREGS_EID, CFE_EVS_EventType_ERROR, "%s not registered with EVS: CC = %lu", + LocalName, (long unsigned int)CFE_EVS_ENABLE_APP_EVENT_TYPE_CC); + } + else if (Status == CFE_EVS_APP_ILLEGAL_APP_ID) + { + EVS_SendEvent(CFE_EVS_ERR_ILLAPPIDRANGE_EID, CFE_EVS_EventType_ERROR, + "Illegal application ID retrieved for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_ENABLE_APP_EVENT_TYPE_CC); + } + else + { + EVS_SendEvent(CFE_EVS_ERR_NOAPPIDFOUND_EID, CFE_EVS_EventType_ERROR, + "Unable to retrieve application ID for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_ENABLE_APP_EVENT_TYPE_CC); + } + + if (Status == CFE_SUCCESS) + { + EVS_SendEvent(CFE_EVS_ENAAPPEVTTYPE_EID, CFE_EVS_EventType_DEBUG, + "Enable App Event Type Command Received with AppName = %s, EventType Bit Mask = 0x%02x", + LocalName, CmdPtr->BitMask); + } + + return Status; + +} /* End CFE_EVS_EnableAppEventTypesCmd */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_DisableAppEventTypesCmd +** +** Purpose: This routine sets the given event type for the given application identifier to a +** disabled state +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_DisableAppEventTypeCmd(const CFE_EVS_DisableAppEventTypeCmd_t *data) +{ + EVS_AppData_t * AppDataPtr; + const CFE_EVS_AppNameBitMaskCmd_Payload_t *CmdPtr = &data->Payload; + int32 Status; + char LocalName[OS_MAX_API_NAME]; + + /* + * Althgouh EVS_GetApplicationInfo() does not require a null terminated argument, + * the value is passed to EVS_SendEvent which does require termination (normal C string) + */ + CFE_SB_MessageStringGet(LocalName, (char *)CmdPtr->AppName, NULL, sizeof(LocalName), sizeof(CmdPtr->AppName)); + + /* Retreive application data */ + Status = EVS_GetApplicationInfo(&AppDataPtr, LocalName); + + if (Status == CFE_SUCCESS) + { + + /* Need to check for an out of range bitmask, since our bit masks are only 4 bits */ + if (CmdPtr->BitMask == 0x0 || CmdPtr->BitMask > 0x0F) + { + EVS_SendEvent(CFE_EVS_ERR_INVALID_BITMASK_EID, CFE_EVS_EventType_ERROR, + "Bit Mask = 0x%08x out of range: CC = %lu", (unsigned int)CmdPtr->BitMask, + (long unsigned int)CFE_EVS_DISABLE_APP_EVENT_TYPE_CC); + Status = CFE_EVS_INVALID_PARAMETER; + } + else + { + EVS_DisableTypes(AppDataPtr, CmdPtr->BitMask); + } + } + else if (Status == CFE_EVS_APP_NOT_REGISTERED) + { + EVS_SendEvent(CFE_EVS_ERR_APPNOREGS_EID, CFE_EVS_EventType_ERROR, "%s not registered with EVS,: CC = %lu", + LocalName, (long unsigned int)CFE_EVS_DISABLE_APP_EVENT_TYPE_CC); + } + else if (Status == CFE_EVS_APP_ILLEGAL_APP_ID) + { + EVS_SendEvent(CFE_EVS_ERR_ILLAPPIDRANGE_EID, CFE_EVS_EventType_ERROR, + "Illegal application ID retrieved for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_DISABLE_APP_EVENT_TYPE_CC); + } + else + { + EVS_SendEvent(CFE_EVS_ERR_NOAPPIDFOUND_EID, CFE_EVS_EventType_ERROR, + "Unable to retrieve application ID for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_DISABLE_APP_EVENT_TYPE_CC); + } + + if (Status == CFE_SUCCESS) + { + EVS_SendEvent(CFE_EVS_DISAPPENTTYPE_EID, CFE_EVS_EventType_DEBUG, + "Disable App Event Type Command Received with AppName = %s, EventType Bit Mask = 0x%02x", + LocalName, (unsigned int)CmdPtr->BitMask); + } + + return Status; + +} /* End CFE_EVS_DisableAppEventTypes */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_EnableAppEventsCmd +** +** Purpose: This routine enables application events for the given application identifier +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_EnableAppEventsCmd(const CFE_EVS_EnableAppEventsCmd_t *data) +{ + EVS_AppData_t * AppDataPtr; + const CFE_EVS_AppNameCmd_Payload_t *CmdPtr = &data->Payload; + int32 Status; + char LocalName[OS_MAX_API_NAME]; + + /* + * Althgouh EVS_GetApplicationInfo() does not require a null terminated argument, + * the value is passed to EVS_SendEvent which does require termination (normal C string) + */ + CFE_SB_MessageStringGet(LocalName, (char *)CmdPtr->AppName, NULL, sizeof(LocalName), sizeof(CmdPtr->AppName)); + + /* Retrieve application data */ + Status = EVS_GetApplicationInfo(&AppDataPtr, LocalName); + + if (Status == CFE_SUCCESS) + { + AppDataPtr->ActiveFlag = true; + + EVS_SendEvent(CFE_EVS_ENAAPPEVT_EID, CFE_EVS_EventType_DEBUG, + "Enable App Events Command Received with AppName = %s", LocalName); + } + else if (Status == CFE_EVS_APP_NOT_REGISTERED) + { + EVS_SendEvent(CFE_EVS_ERR_APPNOREGS_EID, CFE_EVS_EventType_ERROR, "%s not registered with EVS: CC = %lu", + LocalName, (long unsigned int)CFE_EVS_ENABLE_APP_EVENTS_CC); + } + else if (Status == CFE_EVS_APP_ILLEGAL_APP_ID) + { + EVS_SendEvent(CFE_EVS_ERR_ILLAPPIDRANGE_EID, CFE_EVS_EventType_ERROR, + "Illegal application ID retrieved for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_ENABLE_APP_EVENTS_CC); + } + else + { + EVS_SendEvent(CFE_EVS_ERR_NOAPPIDFOUND_EID, CFE_EVS_EventType_ERROR, + "Unable to retrieve application ID for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_ENABLE_APP_EVENTS_CC); + } + + return Status; + +} /* End EVS_EnableAppEventsCmd */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_DisableAppEventsCmd +** +** Purpose: This routine disables application events for the given application identifier +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_DisableAppEventsCmd(const CFE_EVS_DisableAppEventsCmd_t *data) +{ + EVS_AppData_t * AppDataPtr; + const CFE_EVS_AppNameCmd_Payload_t *CmdPtr = &data->Payload; + int32 Status; + char LocalName[OS_MAX_API_NAME]; + + /* + * Althgouh EVS_GetApplicationInfo() does not require a null terminated argument, + * the value is passed to EVS_SendEvent which does require termination (normal C string) + */ + CFE_SB_MessageStringGet(LocalName, (char *)CmdPtr->AppName, NULL, sizeof(LocalName), sizeof(CmdPtr->AppName)); + + /* Retreive application data */ + Status = EVS_GetApplicationInfo(&AppDataPtr, LocalName); + + if (Status == CFE_SUCCESS) + { + AppDataPtr->ActiveFlag = false; + + EVS_SendEvent(CFE_EVS_DISAPPEVT_EID, CFE_EVS_EventType_DEBUG, + "Disable App Events Command Received with AppName = %s", LocalName); + } + else if (Status == CFE_EVS_APP_NOT_REGISTERED) + { + EVS_SendEvent(CFE_EVS_ERR_APPNOREGS_EID, CFE_EVS_EventType_ERROR, "%s not registered with EVS: CC = %lu", + LocalName, (long unsigned int)CFE_EVS_DISABLE_APP_EVENTS_CC); + } + else if (Status == CFE_EVS_APP_ILLEGAL_APP_ID) + { + EVS_SendEvent(CFE_EVS_ERR_ILLAPPIDRANGE_EID, CFE_EVS_EventType_ERROR, + "Illegal application ID retrieved for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_DISABLE_APP_EVENTS_CC); + } + else + { + EVS_SendEvent(CFE_EVS_ERR_NOAPPIDFOUND_EID, CFE_EVS_EventType_ERROR, + "Disable App Events Command: Unable to retrieve application ID for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_DISABLE_APP_EVENTS_CC); + } + + return Status; + +} /* End CFE_EVS_DisableAppEventsCmd */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_ResetAppEventCounterCmd +** +** Purpose: This routine sets the application event counter to zero for the given +** application identifier +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_ResetAppCounterCmd(const CFE_EVS_ResetAppCounterCmd_t *data) +{ + EVS_AppData_t * AppDataPtr; + const CFE_EVS_AppNameCmd_Payload_t *CmdPtr = &data->Payload; + int32 Status; + char LocalName[OS_MAX_API_NAME]; + + /* + * Althgouh EVS_GetApplicationInfo() does not require a null terminated argument, + * the value is passed to EVS_SendEvent which does require termination (normal C string) + */ + CFE_SB_MessageStringGet(LocalName, (char *)CmdPtr->AppName, NULL, sizeof(LocalName), sizeof(CmdPtr->AppName)); + + /* Retreive application data */ + Status = EVS_GetApplicationInfo(&AppDataPtr, LocalName); + + if (Status == CFE_SUCCESS) + { + AppDataPtr->EventCount = 0; + + EVS_SendEvent(CFE_EVS_RSTEVTCNT_EID, CFE_EVS_EventType_DEBUG, + "Reset Event Counter Command Received with AppName = %s", LocalName); + } + else if (Status == CFE_EVS_APP_NOT_REGISTERED) + { + EVS_SendEvent(CFE_EVS_ERR_APPNOREGS_EID, CFE_EVS_EventType_ERROR, "%s not registered with EVS: CC = %lu", + LocalName, (long unsigned int)CFE_EVS_RESET_APP_COUNTER_CC); + } + else if (Status == CFE_EVS_APP_ILLEGAL_APP_ID) + { + EVS_SendEvent(CFE_EVS_ERR_ILLAPPIDRANGE_EID, CFE_EVS_EventType_ERROR, + "Illegal application ID retrieved for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_RESET_APP_COUNTER_CC); + } + else + { + EVS_SendEvent(CFE_EVS_ERR_NOAPPIDFOUND_EID, CFE_EVS_EventType_ERROR, + "Reset Event Counter Command: Unable to retrieve application ID for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_RESET_APP_COUNTER_CC); + } + + return Status; + +} /* End CFE_EVS_ResetAppEventCounterCmd */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_ResetFilterCmd +** +** Purpose: This routine sets the application event filter counter to zero for the given +** application identifier and event identifier +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_ResetFilterCmd(const CFE_EVS_ResetFilterCmd_t *data) +{ + const CFE_EVS_AppNameEventIDCmd_Payload_t *CmdPtr = &data->Payload; + EVS_BinFilter_t * FilterPtr; + int32 Status; + EVS_AppData_t * AppDataPtr; + char LocalName[OS_MAX_API_NAME]; + + /* + * Althgouh EVS_GetApplicationInfo() does not require a null terminated argument, + * the value is passed to EVS_SendEvent which does require termination (normal C string) + */ + CFE_SB_MessageStringGet(LocalName, (char *)CmdPtr->AppName, NULL, sizeof(LocalName), sizeof(CmdPtr->AppName)); + + /* Retreive application data */ + Status = EVS_GetApplicationInfo(&AppDataPtr, LocalName); + + if (Status == CFE_SUCCESS) + { + FilterPtr = EVS_FindEventID(CmdPtr->EventID, AppDataPtr->BinFilters); + + if (FilterPtr != NULL) + { + FilterPtr->Count = 0; + + EVS_SendEvent(CFE_EVS_RSTFILTER_EID, CFE_EVS_EventType_DEBUG, + "Reset Filter Command Received with AppName = %s, EventID = 0x%08x", LocalName, + (unsigned int)CmdPtr->EventID); + } + else + { + EVS_SendEvent(CFE_EVS_ERR_EVTIDNOREGS_EID, CFE_EVS_EventType_ERROR, + "%s Event ID %d not registered for filtering: CC = %lu", LocalName, (int)CmdPtr->EventID, + (long unsigned int)CFE_EVS_RESET_FILTER_CC); + + Status = CFE_EVS_EVT_NOT_REGISTERED; + } + } + else if (Status == CFE_EVS_APP_NOT_REGISTERED) + { + EVS_SendEvent(CFE_EVS_ERR_APPNOREGS_EID, CFE_EVS_EventType_ERROR, "%s not registered with EVS: CC = %lu", + LocalName, (long unsigned int)CFE_EVS_RESET_FILTER_CC); + } + else if (Status == CFE_EVS_APP_ILLEGAL_APP_ID) + { + EVS_SendEvent(CFE_EVS_ERR_ILLAPPIDRANGE_EID, CFE_EVS_EventType_ERROR, + "Illegal application ID retrieved for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_RESET_FILTER_CC); + } + else + { + EVS_SendEvent(CFE_EVS_ERR_NOAPPIDFOUND_EID, CFE_EVS_EventType_ERROR, + "Unable to retrieve application ID for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_RESET_FILTER_CC); + } + + return Status; + +} /* End CFE_EVS_ResetFilterCmd */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_ResetAllFiltersCmd +** +** Purpose: This routine sets all application event filter counters to zero for the given +** application identifier +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_ResetAllFiltersCmd(const CFE_EVS_ResetAllFiltersCmd_t *data) +{ + EVS_AppData_t * AppDataPtr; + const CFE_EVS_AppNameCmd_Payload_t *CmdPtr = &data->Payload; + int32 Status; + uint32 i; + char LocalName[OS_MAX_API_NAME]; + + /* + * Althgouh EVS_GetApplicationInfo() does not require a null terminated argument, + * the value is passed to EVS_SendEvent which does require termination (normal C string) + */ + CFE_SB_MessageStringGet(LocalName, (char *)CmdPtr->AppName, NULL, sizeof(LocalName), sizeof(CmdPtr->AppName)); + + /* Retreive application data */ + Status = EVS_GetApplicationInfo(&AppDataPtr, LocalName); + + if (Status == CFE_SUCCESS) + { + for (i = 0; i < CFE_PLATFORM_EVS_MAX_EVENT_FILTERS; i++) + { + AppDataPtr->BinFilters[i].Count = 0; + } + + EVS_SendEvent(CFE_EVS_RSTALLFILTER_EID, CFE_EVS_EventType_DEBUG, + "Reset All Filters Command Received with AppName = %s", LocalName); + } + else if (Status == CFE_EVS_APP_NOT_REGISTERED) + { + EVS_SendEvent(CFE_EVS_ERR_APPNOREGS_EID, CFE_EVS_EventType_ERROR, "%s not registered with EVS: CC = %lu", + LocalName, (long unsigned int)CFE_EVS_RESET_ALL_FILTERS_CC); + } + else if (Status == CFE_EVS_APP_ILLEGAL_APP_ID) + { + EVS_SendEvent(CFE_EVS_ERR_ILLAPPIDRANGE_EID, CFE_EVS_EventType_ERROR, + "Illegal application ID retrieved for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_RESET_ALL_FILTERS_CC); + } + else + { + EVS_SendEvent(CFE_EVS_ERR_NOAPPIDFOUND_EID, CFE_EVS_EventType_ERROR, + "Unable to retrieve application ID for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_RESET_ALL_FILTERS_CC); + } + + return Status; + +} /* End CFE_EVS_ResetAllFiltersCmd */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_AddEventFilterCmd +** +** Purpose: This routine adds the given event filter for the given application +** identifier and event identifier. +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_AddEventFilterCmd(const CFE_EVS_AddEventFilterCmd_t *data) +{ + const CFE_EVS_AppNameEventIDMaskCmd_Payload_t *CmdPtr = &data->Payload; + EVS_BinFilter_t * FilterPtr; + int32 Status; + EVS_AppData_t * AppDataPtr; + char LocalName[OS_MAX_API_NAME]; + + /* + * Althgouh EVS_GetApplicationInfo() does not require a null terminated argument, + * the value is passed to EVS_SendEvent which does require termination (normal C string) + */ + CFE_SB_MessageStringGet(LocalName, (char *)CmdPtr->AppName, NULL, sizeof(LocalName), sizeof(CmdPtr->AppName)); + + /* Retreive application data */ + Status = EVS_GetApplicationInfo(&AppDataPtr, LocalName); + + if (Status == CFE_SUCCESS) + { + /* Check to see if this event is already registered for filtering */ + FilterPtr = EVS_FindEventID(CmdPtr->EventID, AppDataPtr->BinFilters); + + /* FilterPtr != NULL means that this Event ID was found as already being registered */ + if (FilterPtr != NULL) + { + EVS_SendEvent(CFE_EVS_EVT_FILTERED_EID, CFE_EVS_EventType_ERROR, + "Add Filter Command:AppName = %s, EventID = 0x%08x is already registered for filtering", + LocalName, (unsigned int)CmdPtr->EventID); + + Status = CFE_EVS_EVT_NOT_REGISTERED; + } + else + { + /* now check to see if there is a free slot */ + FilterPtr = EVS_FindEventID(CFE_EVS_FREE_SLOT, AppDataPtr->BinFilters); + + if (FilterPtr != NULL) + { + /* Add Filter Contents */ + FilterPtr->EventID = CmdPtr->EventID; + FilterPtr->Mask = CmdPtr->Mask; + FilterPtr->Count = 0; + + EVS_SendEvent(CFE_EVS_ADDFILTER_EID, CFE_EVS_EventType_DEBUG, + "Add Filter Command Received with AppName = %s, EventID = 0x%08x, Mask = 0x%04x", + LocalName, (unsigned int)CmdPtr->EventID, (unsigned int)CmdPtr->Mask); + } + else + { + EVS_SendEvent(CFE_EVS_ERR_MAXREGSFILTER_EID, CFE_EVS_EventType_ERROR, + "Add Filter Command: number of registered filters has reached max = %d", + CFE_PLATFORM_EVS_MAX_EVENT_FILTERS); + + Status = CFE_EVS_APP_FILTER_OVERLOAD; + } + } /* end else*/ + } /* end if (Status == CFE_SUCCESS) */ + + else if (Status == CFE_EVS_APP_NOT_REGISTERED) + { + EVS_SendEvent(CFE_EVS_ERR_APPNOREGS_EID, CFE_EVS_EventType_ERROR, "%s not registered with EVS: CC = %lu", + LocalName, (long unsigned int)CFE_EVS_ADD_EVENT_FILTER_CC); + } + else if (Status == CFE_EVS_APP_ILLEGAL_APP_ID) + { + EVS_SendEvent(CFE_EVS_ERR_ILLAPPIDRANGE_EID, CFE_EVS_EventType_ERROR, + "Illegal application ID retrieved for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_ADD_EVENT_FILTER_CC); + } + else + { + EVS_SendEvent(CFE_EVS_ERR_NOAPPIDFOUND_EID, CFE_EVS_EventType_ERROR, + "Unable to retrieve application ID for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_ADD_EVENT_FILTER_CC); + } + + return Status; + +} /* CFE_End EVS_AddEventFilterCmd */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_DeleteEventFilterCmd +** +** Purpose: This routine deletes the event filter for the given application +** identifer and event identifier +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_DeleteEventFilterCmd(const CFE_EVS_DeleteEventFilterCmd_t *data) +{ + const CFE_EVS_AppNameEventIDCmd_Payload_t *CmdPtr = &data->Payload; + EVS_BinFilter_t * FilterPtr; + int32 Status; + EVS_AppData_t * AppDataPtr; + char LocalName[OS_MAX_API_NAME]; + + /* + * Althgouh EVS_GetApplicationInfo() does not require a null terminated argument, + * the value is passed to EVS_SendEvent which does require termination (normal C string) + */ + CFE_SB_MessageStringGet(LocalName, (char *)CmdPtr->AppName, NULL, sizeof(LocalName), sizeof(CmdPtr->AppName)); + + /* Retreive application data */ + Status = EVS_GetApplicationInfo(&AppDataPtr, LocalName); + + if (Status == CFE_SUCCESS) + { + FilterPtr = EVS_FindEventID(CmdPtr->EventID, AppDataPtr->BinFilters); + + if (FilterPtr != NULL) + { + /* Clear Filter Contents */ + FilterPtr->EventID = CFE_EVS_FREE_SLOT; + FilterPtr->Mask = CFE_EVS_NO_MASK; + FilterPtr->Count = 0; + + EVS_SendEvent(CFE_EVS_DELFILTER_EID, CFE_EVS_EventType_DEBUG, + "Delete Filter Command Received with AppName = %s, EventID = 0x%08x", LocalName, + (unsigned int)CmdPtr->EventID); + } + else + { + EVS_SendEvent(CFE_EVS_ERR_EVTIDNOREGS_EID, CFE_EVS_EventType_ERROR, + "%s Event ID %d not registered for filtering: CC = %lu", LocalName, (int)CmdPtr->EventID, + (long unsigned int)CFE_EVS_DELETE_EVENT_FILTER_CC); + Status = CFE_EVS_EVT_NOT_REGISTERED; + } + } + else if (Status == CFE_EVS_APP_NOT_REGISTERED) + { + EVS_SendEvent(CFE_EVS_ERR_APPNOREGS_EID, CFE_EVS_EventType_ERROR, "%s not registered with EVS: CC = %lu", + LocalName, (long unsigned int)CFE_EVS_DELETE_EVENT_FILTER_CC); + } + else if (Status == CFE_EVS_APP_ILLEGAL_APP_ID) + { + EVS_SendEvent(CFE_EVS_ERR_ILLAPPIDRANGE_EID, CFE_EVS_EventType_ERROR, + "Illegal application ID retrieved for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_DELETE_EVENT_FILTER_CC); + } + else + { + EVS_SendEvent(CFE_EVS_ERR_NOAPPIDFOUND_EID, CFE_EVS_EventType_ERROR, + "Unable to retrieve application ID for %s: CC = %lu", LocalName, + (long unsigned int)CFE_EVS_DELETE_EVENT_FILTER_CC); + } + + return Status; + +} /* End EVS_DeleteEventFilterCmd */ + +/* +** Function Prologue +** +** Function Name: CFE_EVS_WriteAppDataFileCmd +** +** Purpose: This routine writes all application data to a file for all applications that +** have registered with the EVS. The application data includes the Application ID, +** Active Flag, Event Count, Event Types Active Flag, and Filter Data. +** +** Assumptions and Notes: +** +*/ +int32 CFE_EVS_WriteAppDataFileCmd(const CFE_EVS_WriteAppDataFileCmd_t *data) +{ + int32 Result; + osal_id_t FileHandle = OS_OBJECT_ID_UNDEFINED; + int32 BytesWritten; + uint32 EntryCount = 0; + uint32 i; + static CFE_EVS_AppDataFile_t AppDataFile; + CFE_FS_Header_t FileHdr; + EVS_AppData_t * AppDataPtr; + const CFE_EVS_AppDataCmd_Payload_t *CmdPtr = &data->Payload; + char LocalName[OS_MAX_PATH_LEN]; + + /* + ** Copy the filename into local buffer with default name/path/extension if not specified + */ + Result = CFE_FS_ParseInputFileNameEx(LocalName, CmdPtr->AppDataFilename, sizeof(LocalName), + sizeof(CmdPtr->AppDataFilename), CFE_PLATFORM_EVS_DEFAULT_APP_DATA_FILE, + CFE_FS_GetDefaultMountPoint(CFE_FS_FileCategory_BINARY_DATA_DUMP), + CFE_FS_GetDefaultExtension(CFE_FS_FileCategory_BINARY_DATA_DUMP)); + + if (Result != CFE_SUCCESS) + { + EVS_SendEvent(CFE_EVS_ERR_CRDATFILE_EID, CFE_EVS_EventType_ERROR, + "Write App Data Command Error: CFE_FS_ParseInputFileNameEx() = 0x%08X", (unsigned int)Result); + } + else + { + /* Create Application Data File */ + Result = OS_OpenCreate(&FileHandle, LocalName, OS_FILE_FLAG_CREATE | OS_FILE_FLAG_TRUNCATE, OS_WRITE_ONLY); + + if (Result != OS_SUCCESS) + { + EVS_SendEvent(CFE_EVS_ERR_CRDATFILE_EID, CFE_EVS_EventType_ERROR, + "Write App Data Command Error: OS_OpenCreate = 0x%08X, filename = %s", (unsigned int)Result, + LocalName); + } + } + + if (Result == OS_SUCCESS) + { + /* Result will be overridden if everything works */ + Result = CFE_EVS_FILE_WRITE_ERROR; + + /* Initialize cFE file header */ + CFE_FS_InitHeader(&FileHdr, "EVS Application Data File", CFE_FS_SubType_EVS_APPDATA); + + /* Write cFE file header to the App File */ + BytesWritten = CFE_FS_WriteHeader(FileHandle, &FileHdr); + + if (BytesWritten == sizeof(CFE_FS_Header_t)) + { + AppDataPtr = CFE_EVS_Global.AppData; + for (i = 0; i < CFE_PLATFORM_ES_MAX_APPLICATIONS; i++) + { + /* Only have data for apps that are registered */ + if (EVS_AppDataIsUsed(AppDataPtr)) + { + /* Clear application file data record */ + memset(&AppDataFile, 0, sizeof(CFE_EVS_AppDataFile_t)); + + /* Copy application data to application file data record */ + CFE_ES_GetAppName(AppDataFile.AppName, EVS_AppDataGetID(AppDataPtr), sizeof(AppDataFile.AppName)); + AppDataFile.ActiveFlag = AppDataPtr->ActiveFlag; + AppDataFile.EventCount = AppDataPtr->EventCount; + AppDataFile.EventTypesActiveFlag = AppDataPtr->EventTypesActiveFlag; + + /* Copy application filter data to application file data record */ + memcpy(AppDataFile.Filters, AppDataPtr->BinFilters, + CFE_PLATFORM_EVS_MAX_EVENT_FILTERS * sizeof(EVS_BinFilter_t)); + + /* Write application data record to file */ + BytesWritten = OS_write(FileHandle, &AppDataFile, sizeof(CFE_EVS_AppDataFile_t)); + + if (BytesWritten == sizeof(CFE_EVS_AppDataFile_t)) + { + EntryCount++; + } + else + { + EVS_SendEvent(CFE_EVS_ERR_WRDATFILE_EID, CFE_EVS_EventType_ERROR, + "Write App Data Command Error: OS_write = 0x%08X, filename = %s", + (unsigned int)BytesWritten, LocalName); + break; + } + } + ++AppDataPtr; + } + + /* Process command handler success result */ + if (i == CFE_PLATFORM_ES_MAX_APPLICATIONS) + { + EVS_SendEvent(CFE_EVS_WRDAT_EID, CFE_EVS_EventType_DEBUG, + "Write App Data Command: %d application data entries written to %s", (int)EntryCount, + LocalName); + Result = CFE_SUCCESS; + } + } + + OS_close(FileHandle); + } + + return (Result); + +} /* End CFE_EVS_WriteAppDataFileCmd */ + +/* End cfe_evs_task */ diff --git a/modules/evs/fsw/src/cfe_evs_task.h b/modules/evs/fsw/src/cfe_evs_task.h new file mode 100644 index 000000000..c8c4889f5 --- /dev/null +++ b/modules/evs/fsw/src/cfe_evs_task.h @@ -0,0 +1,162 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/** + * @file + * + * Title: Event Services API - Management Control Interfaces. + * + * Purpose: + * Unit specification for the event services management control interfaces. + * + * Contents: + * I. macro and constant type definitions + * II. EVS internal structures + * III. function prototypes + * + * Design Notes: + * + * References: + * Flight Software Branch C Coding Standard Version 1.0a + * + */ + +#ifndef CFE_EVS_TASK_H +#define CFE_EVS_TASK_H + +/********************************** Include Files ************************************/ +#include "common_types.h" +#include "cfe_platform_cfg.h" +#include "cfe_mission_cfg.h" +#include "osconfig.h" +#include "cfe_evs_api_typedefs.h" +#include "cfe_evs_log_typedef.h" +#include "cfe_sb_api_typedefs.h" +#include "cfe_evs_events.h" + +/********************* Macro and Constant Type Definitions ***************************/ + +#define CFE_EVS_MSG_TRUNCATED '$' +#define CFE_EVS_FREE_SLOT (-1) +#define CFE_EVS_NO_MASK 0 +#define CFE_EVS_PIPE_DEPTH 32 +#define CFE_EVS_MAX_EVENT_SEND_COUNT 65535 +#define CFE_EVS_MAX_FILTER_COUNT 65535 +#define CFE_EVS_PIPE_NAME "EVS_CMD_PIPE" +#define CFE_EVS_MAX_PORT_MSG_LENGTH (CFE_MISSION_EVS_MAX_MESSAGE_LENGTH + OS_MAX_API_NAME + 30) + +/* Since CFE_EVS_MAX_PORT_MSG_LENGTH is the size of the buffer that is sent to + * print out (using OS_printf), we need to check to make sure that the buffer + * size the OS uses is big enough. This check has to be made here because it is + * the first spot after CFE_EVS_MAX_PORT_MSG_LENGTH is defined */ +#if OS_BUFFER_SIZE < CFE_EVS_MAX_PORT_MSG_LENGTH +#error CFE_EVS_MAX_PORT_MSG_LENGTH cannot be greater than OS_BUFFER_SIZE! +#endif + +/************************ Internal Structure Definitions *****************************/ + +typedef struct +{ + int16 EventID; /* Numerical event identifier */ + uint16 Mask; /* Binary filter mask */ + uint16 Count; /* Binary filter counter */ + uint16 Padding; /* Structure padding */ + +} EVS_BinFilter_t; + +typedef struct +{ + CFE_ES_AppId_t AppID; + CFE_ES_AppId_t UnregAppID; + + EVS_BinFilter_t BinFilters[CFE_PLATFORM_EVS_MAX_EVENT_FILTERS]; /* Array of binary filters */ + + uint8 ActiveFlag; /* Application event service active flag */ + uint8 EventTypesActiveFlag; /* Application event types active flag */ + uint16 EventCount; /* Application event counter */ + +} EVS_AppData_t; + +typedef struct +{ + char AppName[OS_MAX_API_NAME]; /* Application name */ + uint8 ActiveFlag; /* Application event service active flag */ + uint8 EventTypesActiveFlag; /* Application event types active flag */ + uint16 EventCount; /* Application event counter */ + EVS_BinFilter_t Filters[CFE_PLATFORM_EVS_MAX_EVENT_FILTERS]; /* Application event filters */ + +} CFE_EVS_AppDataFile_t; + +/* Global data structure */ +typedef struct +{ + EVS_AppData_t AppData[CFE_PLATFORM_ES_MAX_APPLICATIONS]; /* Application state data and event filters */ + + CFE_EVS_Log_t *EVS_LogPtr; /* Pointer to the EVS log in the ES Reset area*/ + /* see cfe_es_global.h */ + + /* + ** EVS task data + */ + CFE_EVS_HousekeepingTlm_t EVS_TlmPkt; + CFE_SB_PipeId_t EVS_CommandPipe; + osal_id_t EVS_SharedDataMutexID; + CFE_ES_AppId_t EVS_AppID; + +} CFE_EVS_Global_t; + +/* + * Global variable specific to EVS module + */ +extern CFE_EVS_Global_t CFE_EVS_Global; + +/***************************** Function Prototypes **********************************/ + +/* + * Functions used within this module and by the unit test + */ +extern int32 CFE_EVS_TaskInit(void); +extern void CFE_EVS_ProcessCommandPacket(CFE_SB_Buffer_t *SBBufPtr); + +/* + * EVS Message Handler Functions + */ +int32 CFE_EVS_ReportHousekeepingCmd(const CFE_MSG_CommandHeader_t *data); +int32 CFE_EVS_NoopCmd(const CFE_EVS_NoopCmd_t *data); +int32 CFE_EVS_ClearLogCmd(const CFE_EVS_ClearLogCmd_t *data); +int32 CFE_EVS_ResetCountersCmd(const CFE_EVS_ResetCountersCmd_t *data); +int32 CFE_EVS_SetFilterCmd(const CFE_EVS_SetFilterCmd_t *data); +int32 CFE_EVS_EnablePortsCmd(const CFE_EVS_EnablePortsCmd_t *data); +int32 CFE_EVS_DisablePortsCmd(const CFE_EVS_DisablePortsCmd_t *data); +int32 CFE_EVS_EnableEventTypeCmd(const CFE_EVS_EnableEventTypeCmd_t *data); +int32 CFE_EVS_DisableEventTypeCmd(const CFE_EVS_DisableEventTypeCmd_t *data); +int32 CFE_EVS_SetEventFormatModeCmd(const CFE_EVS_SetEventFormatModeCmd_t *data); +int32 CFE_EVS_EnableAppEventTypeCmd(const CFE_EVS_EnableAppEventTypeCmd_t *data); +int32 CFE_EVS_DisableAppEventTypeCmd(const CFE_EVS_DisableAppEventTypeCmd_t *data); +int32 CFE_EVS_EnableAppEventsCmd(const CFE_EVS_EnableAppEventsCmd_t *data); +int32 CFE_EVS_DisableAppEventsCmd(const CFE_EVS_DisableAppEventsCmd_t *data); +int32 CFE_EVS_ResetAppCounterCmd(const CFE_EVS_ResetAppCounterCmd_t *data); +int32 CFE_EVS_ResetFilterCmd(const CFE_EVS_ResetFilterCmd_t *data); +int32 CFE_EVS_AddEventFilterCmd(const CFE_EVS_AddEventFilterCmd_t *data); +int32 CFE_EVS_DeleteEventFilterCmd(const CFE_EVS_DeleteEventFilterCmd_t *data); +int32 CFE_EVS_WriteAppDataFileCmd(const CFE_EVS_WriteAppDataFileCmd_t *data); +int32 CFE_EVS_ResetAllFiltersCmd(const CFE_EVS_ResetAllFiltersCmd_t *data); + +#endif /* CFE_EVS_TASK_H */ diff --git a/modules/evs/fsw/src/cfe_evs_utils.c b/modules/evs/fsw/src/cfe_evs_utils.c new file mode 100644 index 000000000..b59350851 --- /dev/null +++ b/modules/evs/fsw/src/cfe_evs_utils.c @@ -0,0 +1,624 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** File: cfe_evs_utils.c +** +** Title: Event Services Utility functions +** +** Purpose: This module defines the utility functions of the +** Event Services Task and API +** +*/ + +/* Include Files */ +#include "cfe_evs_module_all.h" /* All EVS internal definitions and API */ + +#include +#include + +/* Local Function Prototypes */ +void EVS_SendViaPorts(CFE_EVS_LongEventTlm_t *EVS_PktPtr); +void EVS_OutputPort1(char *Message); +void EVS_OutputPort2(char *Message); +void EVS_OutputPort3(char *Message); +void EVS_OutputPort4(char *Message); + +/* Function Definitions */ + +/* +** Function Prologue +** +** Function Name: EVS_GetAppID +** +** Purpose: This routine gets and validates the caller's AppID +** +** Assumptions and Notes: +** +*/ +EVS_AppData_t *EVS_GetAppDataByID(CFE_ES_AppId_t AppID) +{ + uint32 AppIndex; + EVS_AppData_t *AppDataPtr; + + if (CFE_ES_AppID_ToIndex(AppID, &AppIndex) == CFE_SUCCESS && AppIndex < CFE_PLATFORM_ES_MAX_APPLICATIONS) + { + AppDataPtr = &CFE_EVS_Global.AppData[AppIndex]; + } + else + { + AppDataPtr = NULL; + } + + return (AppDataPtr); + +} /* End EVS_GetAppDataByID */ + +int32 EVS_GetCurrentContext(EVS_AppData_t **AppDataOut, CFE_ES_AppId_t *AppIDOut) +{ + CFE_ES_AppId_t AppID; + EVS_AppData_t *AppDataPtr; + int32 Status; + + /* Get the caller's AppID */ + Status = CFE_ES_GetAppID(&AppID); + if (Status == CFE_SUCCESS) + { + AppDataPtr = EVS_GetAppDataByID(AppID); + } + else + { + AppDataPtr = NULL; + } + + if (AppDataPtr == NULL) + { + /* use EVS error/status code */ + Status = CFE_EVS_APP_ILLEGAL_APP_ID; + } + + if (AppIDOut) + { + *AppIDOut = AppID; + } + if (AppDataOut) + { + *AppDataOut = AppDataPtr; + } + + return Status; + +} /* End EVS_GetCurrentContext */ + +/* +** Function Prologue +** +** Function Name: EVS_GetApplicationInfo +** +** Purpose: This routine returns the application ID and +** status specifying the validity of the ID +** +** Assumptions and Notes: +** +*/ +int32 EVS_GetApplicationInfo(EVS_AppData_t **AppDataOut, const char *pAppName) +{ + int32 Status; + CFE_ES_AppId_t AppID; + EVS_AppData_t *AppDataPtr; + + Status = CFE_ES_GetAppIDByName(&AppID, pAppName); + if (Status != CFE_SUCCESS) + { + AppDataPtr = NULL; + } + else + { + AppDataPtr = EVS_GetAppDataByID(AppID); + if (AppDataPtr == NULL) + { + /* + * should not happen - it means the CFE_ES_GetAppIDByName() + * returned a success code with an AppID which was in subsequently + * not accepted by CFE_ES_AppID_ToIndex() + */ + Status = CFE_EVS_APP_ILLEGAL_APP_ID; + } + else if (!EVS_AppDataIsMatch(AppDataPtr, AppID)) + { + /* Avoid outputting a bad pointer */ + AppDataPtr = NULL; + Status = CFE_EVS_APP_NOT_REGISTERED; + } + } + + *AppDataOut = AppDataPtr; + return Status; + +} /* End EVS_GetApplicationInfo */ + +/* +** Function Prologue +** +** Function Name: EVS_NotRegistered +** +** Purpose: This routine sends one "not registered" event per application +** +** Assumptions and Notes: +** +*/ +int32 EVS_NotRegistered(EVS_AppData_t *AppDataPtr, CFE_ES_AppId_t CallerID) +{ + char AppName[OS_MAX_API_NAME]; + + /* Send only one "not registered" event per application */ + if (!CFE_RESOURCEID_TEST_EQUAL(AppDataPtr->UnregAppID, CallerID)) + { + /* Increment count of "not registered" applications */ + CFE_EVS_Global.EVS_TlmPkt.Payload.UnregisteredAppCounter++; + + /* Indicate that "not registered" event has been sent for this app */ + AppDataPtr->UnregAppID = CallerID; + + /* Get the name of the "not registered" app */ + CFE_ES_GetAppName(AppName, CallerID, sizeof(AppName)); + + /* Send the "not registered" event */ + EVS_SendEvent(CFE_EVS_ERR_UNREGISTERED_EVS_APP, CFE_EVS_EventType_ERROR, + "App %s not registered with Event Services. Unable to send event.", AppName); + + /* Write the "not registered" info to the system log */ + CFE_ES_WriteToSysLog("App %s not registered with Event Services. Unable to send event.\n", AppName); + } + + return (CFE_EVS_APP_NOT_REGISTERED); + +} /* End EVS_NotRegistered */ + +/* +** Function Prologue +** +** Function Name: EVS_IsFiltered +** +** Purpose: This routine returns true if the given event identifier and event type +** is filtered for the given application identifier. Otherwise a value of +** false is returned. +** +** Assumptions and Notes: +** +*/ +bool EVS_IsFiltered(EVS_AppData_t *AppDataPtr, uint16 EventID, uint16 EventType) +{ + EVS_BinFilter_t *FilterPtr; + bool Filtered = false; + char AppName[OS_MAX_API_NAME]; + + if (AppDataPtr->ActiveFlag == false) + { + /* All events are disabled for this application */ + Filtered = true; + } + else + switch (EventType) + { + case CFE_EVS_EventType_DEBUG: + + if ((AppDataPtr->EventTypesActiveFlag & CFE_EVS_DEBUG_BIT) == 0) + { + /* Debug events are disabled for this application */ + Filtered = true; + } + break; + + case CFE_EVS_EventType_INFORMATION: + + if ((AppDataPtr->EventTypesActiveFlag & CFE_EVS_INFORMATION_BIT) == 0) + { + /* Informational events are disabled for this application */ + Filtered = true; + } + break; + + case CFE_EVS_EventType_ERROR: + + if ((AppDataPtr->EventTypesActiveFlag & CFE_EVS_ERROR_BIT) == 0) + { + /* Error events are disabled for this application */ + Filtered = true; + } + break; + + case CFE_EVS_EventType_CRITICAL: + + if ((AppDataPtr->EventTypesActiveFlag & CFE_EVS_CRITICAL_BIT) == 0) + { + /* Critical events are disabled for this application */ + Filtered = true; + } + break; + + default: + + /* Invalid Event Type */ + Filtered = true; + break; + } + + /* Is this type of event enabled for this application? */ + if (Filtered == false) + { + FilterPtr = EVS_FindEventID(EventID, AppDataPtr->BinFilters); + + /* Does this event ID have an event filter table entry? */ + if (FilterPtr != NULL) + { + if ((FilterPtr->Mask & FilterPtr->Count) != 0) + { + /* This iteration of the event ID is filtered */ + Filtered = true; + } + + if (FilterPtr->Count < CFE_EVS_MAX_FILTER_COUNT) + { + /* Maintain event iteration count */ + FilterPtr->Count++; + + /* Is it time to lock this filter? */ + if (FilterPtr->Count == CFE_EVS_MAX_FILTER_COUNT) + { + CFE_ES_GetAppName(AppName, EVS_AppDataGetID(AppDataPtr), sizeof(AppName)); + + EVS_SendEvent(CFE_EVS_FILTER_MAX_EID, CFE_EVS_EventType_INFORMATION, + "Max filter count reached, AppName = %s, EventID = 0x%08x: Filter locked until reset", + AppName, (unsigned int)EventID); + } + } + } + } + + return (Filtered); + +} /* End EVS_IsFiltered */ + +/* +** Function Prologue +** +** Function Name: EVS_FindEventID +** +** Purpose: This routine searches and returns an index to the given Event ID with the +** given application filter array. +** +** Assumptions and Notes: +** +*/ +EVS_BinFilter_t *EVS_FindEventID(int16 EventID, EVS_BinFilter_t *FilterArray) +{ + uint32 i; + + for (i = 0; i < CFE_PLATFORM_EVS_MAX_EVENT_FILTERS; i++) + { + if (FilterArray[i].EventID == EventID) + { + return (&FilterArray[i]); + } + } + + return ((EVS_BinFilter_t *)NULL); + +} /* End EVS_FindEventID */ + +/* +** Function Prologue +** +** Function Name: EVS_EnableTypes +** +** Purpose: This routine enables event types selected in BitMask +** +** Assumptions and Notes: +** +*/ +void EVS_EnableTypes(EVS_AppData_t *AppDataPtr, uint8 BitMask) +{ + uint8 EventTypeBits = (CFE_EVS_DEBUG_BIT | CFE_EVS_INFORMATION_BIT | CFE_EVS_ERROR_BIT | CFE_EVS_CRITICAL_BIT); + + /* Enable selected event type bits from bitmask */ + AppDataPtr->EventTypesActiveFlag |= (BitMask & EventTypeBits); + +} /* End EVS_EnableTypes */ + +/* +** Function Prologue +** +** Function Name: EVS_DisableTypes +** +** Purpose: This routine disables event types selected in BitMask +** +** Assumptions and Notes: +** +*/ +void EVS_DisableTypes(EVS_AppData_t *AppDataPtr, uint8 BitMask) +{ + uint8 EventTypeBits = (CFE_EVS_DEBUG_BIT | CFE_EVS_INFORMATION_BIT | CFE_EVS_ERROR_BIT | CFE_EVS_CRITICAL_BIT); + + /* Disable selected event type bits from bitmask */ + AppDataPtr->EventTypesActiveFlag &= ~(BitMask & EventTypeBits); + +} /* End EVS_DisableTypes */ + +/* +** Function Prologue +** +** Function Name: EVS_GenerateEventTelemetry +** +** Purpose: This routine sends an EVS event message out the software bus and all +** enabled output ports +** +** Assumptions and Notes: +** This always generates a "long" style message for logging purposes. +** If configured for long events the same message is sent on the software bus as well. +** If configured for short events, a separate short message is generated using a subset +** of the information from the long message. +*/ +void EVS_GenerateEventTelemetry(EVS_AppData_t *AppDataPtr, uint16 EventID, uint16 EventType, + const CFE_TIME_SysTime_t *TimeStamp, const char *MsgSpec, va_list ArgPtr) +{ + CFE_EVS_LongEventTlm_t LongEventTlm; /* The "long" flavor is always generated, as this is what is logged */ + CFE_EVS_ShortEventTlm_t ShortEventTlm; /* The "short" flavor is only generated if selected */ + int ExpandedLength; + + /* Initialize EVS event packets */ + CFE_MSG_Init(&LongEventTlm.TlmHeader.Msg, CFE_SB_ValueToMsgId(CFE_EVS_LONG_EVENT_MSG_MID), sizeof(LongEventTlm)); + LongEventTlm.Payload.PacketID.EventID = EventID; + LongEventTlm.Payload.PacketID.EventType = EventType; + + /* vsnprintf() returns the total expanded length of the formatted string */ + /* vsnprintf() copies and zero terminates portion that fits in the buffer */ + ExpandedLength = + vsnprintf((char *)LongEventTlm.Payload.Message, sizeof(LongEventTlm.Payload.Message), MsgSpec, ArgPtr); + + /* + * If vsnprintf is bigger than message size, mark with truncation character + * Note negative returns (error from vsnprintf) will just leave the message as-is + */ + if (ExpandedLength >= (int)sizeof(LongEventTlm.Payload.Message)) + { + /* Mark character before zero terminator to indicate truncation */ + LongEventTlm.Payload.Message[sizeof(LongEventTlm.Payload.Message) - 2] = CFE_EVS_MSG_TRUNCATED; + CFE_EVS_Global.EVS_TlmPkt.Payload.MessageTruncCounter++; + } + + /* Obtain task and system information */ + CFE_ES_GetAppName((char *)LongEventTlm.Payload.PacketID.AppName, EVS_AppDataGetID(AppDataPtr), + sizeof(LongEventTlm.Payload.PacketID.AppName)); + LongEventTlm.Payload.PacketID.SpacecraftID = CFE_PSP_GetSpacecraftId(); + LongEventTlm.Payload.PacketID.ProcessorID = CFE_PSP_GetProcessorId(); + + /* Set the packet timestamp */ + CFE_MSG_SetMsgTime(&LongEventTlm.TlmHeader.Msg, *TimeStamp); + + /* Write event to the event log */ + EVS_AddLog(&LongEventTlm); + + /* Send event via selected ports */ + EVS_SendViaPorts(&LongEventTlm); + + if (CFE_EVS_Global.EVS_TlmPkt.Payload.MessageFormatMode == CFE_EVS_MsgFormat_LONG) + { + /* Send long event via SoftwareBus */ + CFE_SB_TransmitMsg(&LongEventTlm.TlmHeader.Msg, true); + } + else if (CFE_EVS_Global.EVS_TlmPkt.Payload.MessageFormatMode == CFE_EVS_MsgFormat_SHORT) + { + /* + * Initialize the short format event message from data that was already + * gathered in the long format message (short format is a subset) + * + * This goes out on a separate message ID. + */ + CFE_MSG_Init(&ShortEventTlm.TlmHeader.Msg, CFE_SB_ValueToMsgId(CFE_EVS_SHORT_EVENT_MSG_MID), + sizeof(ShortEventTlm)); + CFE_MSG_SetMsgTime(&ShortEventTlm.TlmHeader.Msg, *TimeStamp); + ShortEventTlm.Payload.PacketID = LongEventTlm.Payload.PacketID; + CFE_SB_TransmitMsg(&ShortEventTlm.TlmHeader.Msg, true); + } + + /* Increment message send counters (prevent rollover) */ + if (CFE_EVS_Global.EVS_TlmPkt.Payload.MessageSendCounter < CFE_EVS_MAX_EVENT_SEND_COUNT) + { + CFE_EVS_Global.EVS_TlmPkt.Payload.MessageSendCounter++; + } + + if (AppDataPtr->EventCount < CFE_EVS_MAX_EVENT_SEND_COUNT) + { + AppDataPtr->EventCount++; + } + +} /* End EVS_GenerateEventTelemetry */ + +/* +** Function Prologue +** +** Function Name: EVS_SendViaPorts +** +** Purpose: This routine sends a string event message out all enabled +** output ports +** +** Assumptions and Notes: +*/ +void EVS_SendViaPorts(CFE_EVS_LongEventTlm_t *EVS_PktPtr) +{ + char PortMessage[CFE_EVS_MAX_PORT_MSG_LENGTH]; + + if (((CFE_EVS_Global.EVS_TlmPkt.Payload.OutputPort & CFE_EVS_PORT1_BIT) >> 0) == true) + { + /* Copy event message to string format */ + snprintf(PortMessage, CFE_EVS_MAX_PORT_MSG_LENGTH, "EVS Port1 %u/%u/%s %u: %s", + (unsigned int)EVS_PktPtr->Payload.PacketID.SpacecraftID, + (unsigned int)EVS_PktPtr->Payload.PacketID.ProcessorID, EVS_PktPtr->Payload.PacketID.AppName, + (unsigned int)EVS_PktPtr->Payload.PacketID.EventID, EVS_PktPtr->Payload.Message); + /* Send string event out port #1 */ + EVS_OutputPort1(PortMessage); + } + + if (((CFE_EVS_Global.EVS_TlmPkt.Payload.OutputPort & CFE_EVS_PORT2_BIT) >> 1) == true) + { + /* Copy event message to string format */ + snprintf(PortMessage, CFE_EVS_MAX_PORT_MSG_LENGTH, "EVS Port2 %u/%u/%s %u: %s", + (unsigned int)EVS_PktPtr->Payload.PacketID.SpacecraftID, + (unsigned int)EVS_PktPtr->Payload.PacketID.ProcessorID, EVS_PktPtr->Payload.PacketID.AppName, + (unsigned int)EVS_PktPtr->Payload.PacketID.EventID, EVS_PktPtr->Payload.Message); + /* Send string event out port #2 */ + EVS_OutputPort2(PortMessage); + } + + if (((CFE_EVS_Global.EVS_TlmPkt.Payload.OutputPort & CFE_EVS_PORT3_BIT) >> 2) == true) + { + /* Copy event message to string format */ + snprintf(PortMessage, CFE_EVS_MAX_PORT_MSG_LENGTH, "EVS Port3 %u/%u/%s %u: %s", + (unsigned int)EVS_PktPtr->Payload.PacketID.SpacecraftID, + (unsigned int)EVS_PktPtr->Payload.PacketID.ProcessorID, EVS_PktPtr->Payload.PacketID.AppName, + (unsigned int)EVS_PktPtr->Payload.PacketID.EventID, EVS_PktPtr->Payload.Message); + /* Send string event out port #3 */ + EVS_OutputPort3(PortMessage); + } + + if (((CFE_EVS_Global.EVS_TlmPkt.Payload.OutputPort & CFE_EVS_PORT4_BIT) >> 3) == true) + { + /* Copy event message to string format */ + snprintf(PortMessage, CFE_EVS_MAX_PORT_MSG_LENGTH, "EVS Port4 %u/%u/%s %u: %s", + (unsigned int)EVS_PktPtr->Payload.PacketID.SpacecraftID, + (unsigned int)EVS_PktPtr->Payload.PacketID.ProcessorID, EVS_PktPtr->Payload.PacketID.AppName, + (unsigned int)EVS_PktPtr->Payload.PacketID.EventID, EVS_PktPtr->Payload.Message); + /* Send string event out port #4 */ + EVS_OutputPort4(PortMessage); + } + +} /* End SendViaPorts */ + +/* +** Function Prologue +** +** Function Name: EVS_OutputPort1 +** +** Purpose: This routine sends the input message string out +** EVS port 1 +** +** Assumptions and Notes: +** +*/ +void EVS_OutputPort1(char *Message) +{ + OS_printf("%s\n", Message); + +} /* End ES_OutputPort1 */ + +/* +** Function Prologue +** +** Function Name: EVS_OutputPort2 +** +** Purpose: This routine sends the input message string out +** EVS port 2 +** +** Assumptions and Notes: +** +*/ +void EVS_OutputPort2(char *Message) +{ + OS_printf("%s\n", Message); + +} /* End ES_OutputPort2 */ + +/* +** Function Prologue +** +** Function Name: EVS_OutputPort3 +** +** Purpose: This routine sends the input message string out +** EVS port 3 +** +** Assumptions and Notes: +** +*/ +void EVS_OutputPort3(char *Message) +{ + OS_printf("%s\n", Message); + +} /* End ES_OutputPort3 */ + +/* +** Function Prologue +** +** Function Name: EVS_OutputPort4 +** +** Purpose: This routine sends the input message string out +** EVS port 4 +** +** Assumptions and Notes: +** +*/ +void EVS_OutputPort4(char *Message) +{ + OS_printf("%s\n", Message); + +} /* End ES_OutputPort4 */ + +/* +** Function Prologue +** +** Function Name: EVS_SendEvent +** +** Purpose: This routine allows EVS to send events without having to verify +** that the caller has a valid AppID and has registered with EVS. +** This routine also does not need to acquire the mutex semaphore, +** which can be time consuming on some platforms. +** +** Assumptions and Notes: +*/ +int32 EVS_SendEvent(uint16 EventID, uint16 EventType, const char *Spec, ...) +{ + CFE_TIME_SysTime_t Time; + va_list Ptr; + EVS_AppData_t * AppDataPtr; + + /* + * Must check that EVS_AppID is valid, which can happen if this is called + * by some other thread before CFE_EVS_TaskInit() runs + */ + AppDataPtr = EVS_GetAppDataByID(CFE_EVS_Global.EVS_AppID); + + /* Unlikely, but possible that an EVS event filter was added by command */ + if (EVS_AppDataIsMatch(AppDataPtr, CFE_EVS_Global.EVS_AppID) && + EVS_IsFiltered(AppDataPtr, EventID, EventType) == false) + { + /* Get current spacecraft time */ + Time = CFE_TIME_GetTime(); + + /* Send the event packets */ + va_start(Ptr, Spec); + EVS_GenerateEventTelemetry(AppDataPtr, EventID, EventType, &Time, Spec, Ptr); + va_end(Ptr); + } + + return (CFE_SUCCESS); + +} /* End EVS_SendEvent */ + +/* End cfe_evs_utils */ diff --git a/modules/evs/fsw/src/cfe_evs_utils.h b/modules/evs/fsw/src/cfe_evs_utils.h new file mode 100644 index 000000000..e90f7c653 --- /dev/null +++ b/modules/evs/fsw/src/cfe_evs_utils.h @@ -0,0 +1,176 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/** + * @file + * + * Title: Event Services Task and API - Utility functions. + * + * Purpose: + * Unit specification for the event services utility functions. + * + * Contents: + * I. macro and constant type definitions + * II. EVS utility internal structures + * III. function prototypes + * + * Design Notes: + * + * References: + * Flight Software Branch C Coding Standard Version 1.0a + * + */ + +#ifndef CFE_EVS_UTILS_H +#define CFE_EVS_UTILS_H + +/********************* Include Files ************************/ + +#include "cfe_evs_task.h" /* EVS internal definitions */ +#include "cfe_resourceid.h" +#include "cfe_es_api_typedefs.h" +#include "cfe_time_api_typedefs.h" + +/* ============== Section I: Macro and Constant Type Definitions =========== */ + +/* ============== Section II: Internal Structures ============ */ + +/* ============== Section III: Function Prototypes =========== */ + +/** + * @brief Obtain the EVS app record for the given ID + * + * This only obtains a pointer to where the record should be, it does + * not check/confirm that the record actually is for the given AppID. + * Use EVS_AppDataIsMatch() to determine if the record is valid. + * + * @sa EVS_AppDataIsMatch() + * + * @param[in] AppID AppID to find + * @returns Pointer to app table entry, or NULL if ID is invalid. + */ +EVS_AppData_t *EVS_GetAppDataByID(CFE_ES_AppId_t AppID); + +/** + * @brief Obtain the context information for the currently running app + * + * Obtains both the AppData record (pointer) and AppID for the current context. + * + * @param[out] AppDataOut Location to store App Data record pointer + * @param[out] AppIDOut Location to store AppID + * @returns CFE_SUCCESS if successful, or relevant error code. + */ +int32 EVS_GetCurrentContext(EVS_AppData_t **AppDataOut, CFE_ES_AppId_t *AppIDOut); + +/** + * @brief Check if an EVS app record is in use or free/empty + * + * This routine checks if the EVS app entry is in use or if it is free + * + * As this dereferences fields within the record, global data must be + * locked prior to invoking this function. + * + * @param[in] AppDataPtr pointer to app table entry + * @returns true if the entry is in use/configured, or false if it is free/empty + */ +static inline bool EVS_AppDataIsUsed(EVS_AppData_t *AppDataPtr) +{ + return CFE_RESOURCEID_TEST_DEFINED(AppDataPtr->AppID); +} + +/** + * @brief Get the ID value from an EVS table entry + * + * This routine converts the table entry back to an abstract ID. + * + * @param[in] AppDataPtr pointer to app table entry + * @returns AppID of entry + */ +static inline CFE_ES_AppId_t EVS_AppDataGetID(EVS_AppData_t *AppDataPtr) +{ + /* + * The initial implementation does not store the ID in the entry; + * the ID is simply the zero-based index into the table. + */ + return (AppDataPtr->AppID); +} + +/** + * @brief Marks an EVS table entry as used (not free) + * + * This sets the internal field(s) within this entry, and marks + * it as being associated with the given app ID. + * + * As this dereferences fields within the record, global data must be + * locked prior to invoking this function. + * + * @param[in] AppDataPtr pointer to app table entry + * @param[in] AppID the app ID of this entry + */ +static inline void EVS_AppDataSetUsed(EVS_AppData_t *AppDataPtr, CFE_ES_AppId_t AppID) +{ + AppDataPtr->AppID = AppID; +} + +/** + * @brief Set an EVS table entry free (not used) + * + * This clears the internal field(s) within this entry, and allows the + * memory to be re-used in the future. + * + * @param[in] AppDataPtr pointer to app table entry + */ +static inline void EVS_AppDataSetFree(EVS_AppData_t *AppDataPtr) +{ + AppDataPtr->AppID = CFE_ES_APPID_UNDEFINED; +} + +/** + * @brief Check if an EVS record is a match for the given AppID + * + * This routine confirms that the previously-located record is valid + * and matches the expected app ID. + * + * @param[in] AppDataPtr pointer to app table entry + * @param[in] AppID expected app ID + * @returns true if the entry matches the given app ID + */ +static inline bool EVS_AppDataIsMatch(EVS_AppData_t *AppDataPtr, CFE_ES_AppId_t AppID) +{ + return (AppDataPtr != NULL && CFE_RESOURCEID_TEST_EQUAL(AppDataPtr->AppID, AppID)); +} + +int32 EVS_GetApplicationInfo(EVS_AppData_t **AppDataOut, const char *pAppName); + +int32 EVS_NotRegistered(EVS_AppData_t *AppDataPtr, CFE_ES_AppId_t CallerID); + +bool EVS_IsFiltered(EVS_AppData_t *AppDataPtr, uint16 EventID, uint16 EventType); + +EVS_BinFilter_t *EVS_FindEventID(int16 EventID, EVS_BinFilter_t *FilterArray); + +void EVS_EnableTypes(EVS_AppData_t *AppDataPtr, uint8 BitMask); +void EVS_DisableTypes(EVS_AppData_t *AppDataPtr, uint8 BitMask); + +void EVS_GenerateEventTelemetry(EVS_AppData_t *AppDataPtr, uint16 EventID, uint16 EventType, + const CFE_TIME_SysTime_t *Time, const char *MsgSpec, va_list ArgPtr); + +int32 EVS_SendEvent(uint16 EventID, uint16 EventType, const char *Spec, ...); + +#endif /* CFE_EVS_UTILS_H */ diff --git a/modules/evs/fsw/src/cfe_evs_verify.h b/modules/evs/fsw/src/cfe_evs_verify.h new file mode 100644 index 000000000..d94de4d20 --- /dev/null +++ b/modules/evs/fsw/src/cfe_evs_verify.h @@ -0,0 +1,66 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/** + * @file + * + * Purpose: + * This header file performs compile time checking for EVS configuration + * parameters. + * + * Author: K.Audra(Microtel) + * + * Notes: + * + */ + +#ifndef CFE_EVS_VERIFY_H +#define CFE_EVS_VERIFY_H + +/* NOTE: Besides the checks in this file, there is one more in cfe_evs_task.h. + * The check is not here because it is checking a local #define based on a + * configuration parameter + */ + +#if CFE_PLATFORM_EVS_DEFAULT_TYPE_FLAG > 0x0F +#error CFE_PLATFORM_EVS_DEFAULT_TYPE_FLAG cannot be more than 0x0F! +#endif + +#if (CFE_PLATFORM_EVS_DEFAULT_LOG_MODE != 0) && (CFE_PLATFORM_EVS_DEFAULT_LOG_MODE != 1) +#error CFE_PLATFORM_EVS_DEFAULT_LOG_MODE can only be 0 (Overwrite) or 1 (Discard)! +#endif + +#if (CFE_PLATFORM_EVS_DEFAULT_MSG_FORMAT_MODE != CFE_EVS_MsgFormat_LONG) && \ + (CFE_PLATFORM_EVS_DEFAULT_MSG_FORMAT_MODE != CFE_EVS_MsgFormat_SHORT) +#error CFE_EVS_DEFAULT_MSG_FORMAT can only be CFE_EVS_MsgFormat_LONG or CFE_EVS_MsgFormat_SHORT ! +#endif + +#if CFE_PLATFORM_EVS_PORT_DEFAULT > 0x0F +#error CFE_PLATFORM_EVS_PORT_DEFAULT cannot be greater than 0x0F! +#endif + +/* +** Validate task stack size... +*/ +#if CFE_PLATFORM_EVS_START_TASK_STACK_SIZE < 2048 +#error CFE_PLATFORM_EVS_START_TASK_STACK_SIZE must be greater than or equal to 2048 +#endif + +#endif /* CFE_EVS_VERIFY_H */ diff --git a/modules/fs/CMakeLists.txt b/modules/fs/CMakeLists.txt new file mode 100644 index 000000000..db9b570d6 --- /dev/null +++ b/modules/fs/CMakeLists.txt @@ -0,0 +1,25 @@ +################################################################## +# +# cFE File Services (FS) module CMake build recipe +# +################################################################## + +project(CFE_FS C) + +# File services source files +set(fs_SOURCES + fsw/src/cfe_fs_api.c + fsw/src/cfe_fs_priv.c + fsw/src/cfe_fs_api.c + fsw/src/cfe_fs_priv.c +) +add_library(fs STATIC ${fs_SOURCES}) + +target_include_directories(fs PUBLIC fsw/inc) +target_link_libraries(fs PRIVATE core_private) + +# Add unit test coverage subdirectory +if(ENABLE_UNIT_TESTS) + add_subdirectory(ut-coverage) +endif(ENABLE_UNIT_TESTS) + diff --git a/modules/fs/fsw/src/cfe_fs_api.c b/modules/fs/fsw/src/cfe_fs_api.c new file mode 100644 index 000000000..b3703eedf --- /dev/null +++ b/modules/fs/fsw/src/cfe_fs_api.c @@ -0,0 +1,886 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** File: cfe_fs_api.c +** +** Purpose: cFE File Services (FS) library API source file +** +** Author: S.Walling/Microtel +** +** Notes: +** +*/ + +/* +** Required header files... +*/ +#include "cfe_fs_module_all.h" + +#include + +/* The target config allows refs into global CONFIGDATA object(s) */ +#include "target_config.h" + +/* + * Fixed default file system extensions (not platform dependent) + */ +const char CFE_FS_DEFAULT_SCRIPT_EXTENSION[] = ".scr"; +const char CFE_FS_DEFAULT_DUMP_FILE_EXTENSION[] = ".dat"; +const char CFE_FS_DEFAULT_TEMP_FILE_EXTENSION[] = ".tmp"; +const char CFE_FS_DEFAULT_LOG_FILE_EXTENSION[] = ".log"; + +const char *CFE_FS_GetDefaultMountPoint(CFE_FS_FileCategory_t FileCategory) +{ + const char *Result; + + switch (FileCategory) + { + case CFE_FS_FileCategory_SCRIPT: + case CFE_FS_FileCategory_DYNAMIC_MODULE: + /* scripts and app/lib modules reside in the non-volatile/CF mount by default */ + Result = GLOBAL_CFE_CONFIGDATA.NonvolMountPoint; + break; + case CFE_FS_FileCategory_TEMP: + case CFE_FS_FileCategory_BINARY_DATA_DUMP: + case CFE_FS_FileCategory_TEXT_LOG: + /* temporary and data dump files are put in the RAM DISK mount by default */ + Result = GLOBAL_CFE_CONFIGDATA.RamdiskMountPoint; + break; + default: + Result = NULL; /* Should not be used */ + break; + } + + return Result; +} + +const char *CFE_FS_GetDefaultExtension(CFE_FS_FileCategory_t FileCategory) +{ + const char *Result; + + switch (FileCategory) + { + case CFE_FS_FileCategory_SCRIPT: + Result = CFE_FS_DEFAULT_SCRIPT_EXTENSION; + break; + case CFE_FS_FileCategory_DYNAMIC_MODULE: + /* app/lib modules use a platform-specific extension, and the + * default is derived from the build system */ + Result = GLOBAL_CONFIGDATA.Default_ModuleExtension; + break; + case CFE_FS_FileCategory_TEMP: + Result = CFE_FS_DEFAULT_TEMP_FILE_EXTENSION; + break; + case CFE_FS_FileCategory_BINARY_DATA_DUMP: + Result = CFE_FS_DEFAULT_DUMP_FILE_EXTENSION; + break; + case CFE_FS_FileCategory_TEXT_LOG: + Result = CFE_FS_DEFAULT_LOG_FILE_EXTENSION; + break; + default: + Result = NULL; /* Should not be used */ + break; + } + + return Result; +} + +/* +** CFE_FS_ReadHeader() - See API and header file for details +*/ +int32 CFE_FS_ReadHeader(CFE_FS_Header_t *Hdr, osal_id_t FileDes) +{ + int32 Result; + int32 EndianCheck = 0x01020304; + + if (Hdr == NULL) + { + return CFE_FS_BAD_ARGUMENT; + } + + /* + ** Ensure that we are at the start of the file... + */ + Result = OS_lseek(FileDes, 0, OS_SEEK_SET); + + if (Result == OS_SUCCESS) + { + /* + ** Read header structure into callers buffer... + */ + Result = OS_read(FileDes, Hdr, sizeof(CFE_FS_Header_t)); + + /* Determine if this processor is a little endian processor */ + if ((*(char *)(&EndianCheck)) == 0x04) + { + /* If this is a little endian processor, then convert the header data structure from */ + /* its standard big-endian format into a little endian format to ease user access */ + CFE_FS_ByteSwapCFEHeader(Hdr); + } + } + + return (Result); + +} /* End of CFE_FS_ReadHeader() */ + +/* +** CFE_FS_InitHeader() - See API and header file for details +*/ +void CFE_FS_InitHeader(CFE_FS_Header_t *Hdr, const char *Description, uint32 SubType) +{ + if (Hdr == NULL || Description == NULL) + { + CFE_ES_WriteToSysLog("CFE_FS:InitHeader-Failed invalid arguments\n"); + } + else + { + memset(Hdr, 0, sizeof(CFE_FS_Header_t)); + strncpy((char *)Hdr->Description, Description, sizeof(Hdr->Description) - 1); + Hdr->SubType = SubType; + } +} + +/* +** CFE_FS_WriteHeader() - See API and header file for details +*/ +int32 CFE_FS_WriteHeader(osal_id_t FileDes, CFE_FS_Header_t *Hdr) +{ + CFE_TIME_SysTime_t Time; + int32 Result; + int32 EndianCheck = 0x01020304; + CFE_ES_AppId_t AppID; + + if (Hdr == NULL) + { + return CFE_FS_BAD_ARGUMENT; + } + + /* + ** Ensure that we are at the start of the file... + */ + Result = OS_lseek(FileDes, 0, OS_SEEK_SET); + + if (Result == OS_SUCCESS) + { + /* + ** Fill in the ID fields... + */ + Hdr->SpacecraftID = CFE_PSP_GetSpacecraftId(); + Hdr->ProcessorID = CFE_PSP_GetProcessorId(); + CFE_ES_GetAppID(&AppID); + Hdr->ApplicationID = CFE_RESOURCEID_TO_ULONG(AppID); + + /* Fill in length field */ + + Hdr->Length = sizeof(CFE_FS_Header_t); + + /* put the header, 'cfe1' in hex, in to the content type */ + Hdr->ContentType = 0x63464531; + + /* + ** Fill in the timestamp fields... + */ + Time = CFE_TIME_GetTime(); + Hdr->TimeSeconds = Time.Seconds; + Hdr->TimeSubSeconds = Time.Subseconds; + + /* + ** Determine if this is a little endian processor + */ + if ((*(char *)(&EndianCheck)) == 0x04) + { + /* If this is a little endian processor, then convert the header data structure from */ + /* the native little endian format to the required CFE standard big endian format */ + CFE_FS_ByteSwapCFEHeader(Hdr); + } + + /* + ** Write header structure from callers buffer... + */ + Result = OS_write(FileDes, Hdr, sizeof(CFE_FS_Header_t)); + + /* + ** Determine if this is a little endian processor + */ + if ((*(char *)(&EndianCheck)) == 0x04) + { + /* If this is a little endian processor, then convert the header data structure back */ + /* from the required CFE standard big endian format to the little endian format */ + CFE_FS_ByteSwapCFEHeader(Hdr); + } + } + + return (Result); + +} /* End of CFE_FS_WriteHeader() */ + +/* +** CFE_FS_SetTimestamp - See API and header file for details +*/ +int32 CFE_FS_SetTimestamp(osal_id_t FileDes, CFE_TIME_SysTime_t NewTimestamp) +{ + int32 Result; + CFE_FS_Header_t TempHdr; + int32 EndianCheck = 0x01020304; + CFE_TIME_SysTime_t OutTimestamp = NewTimestamp; + int32 FileOffset = 0; + + FileOffset = ((char *)&TempHdr.TimeSeconds - (char *)&TempHdr.ContentType); + Result = OS_lseek(FileDes, FileOffset, OS_SEEK_SET); + + if (Result == FileOffset) + { + /* + ** Determine if this is a little endian processor + */ + if ((*(char *)(&EndianCheck)) == 0x04) + { + /* If this processor is a little endian processor, then convert the timestamp to a big */ + /* endian format so that it is compatible with the standard cFE File Header format */ + CFE_FS_ByteSwapUint32(&OutTimestamp.Seconds); + CFE_FS_ByteSwapUint32(&OutTimestamp.Subseconds); + } + + Result = OS_write(FileDes, &OutTimestamp.Seconds, sizeof(OutTimestamp.Seconds)); + + /* On a good write, the value returned will equal the number of bytes written */ + if (Result == sizeof(OutTimestamp.Seconds)) + { + Result = OS_write(FileDes, &OutTimestamp.Subseconds, sizeof(OutTimestamp.Subseconds)); + + if (Result == sizeof(OutTimestamp.Subseconds)) + { + Result = OS_SUCCESS; + } + else + { + CFE_ES_WriteToSysLog("CFE_FS:SetTime-Failed to write Seconds (Status=0x%08X)\n", (unsigned int)Result); + } + } + else + { + CFE_ES_WriteToSysLog("CFE_FS:SetTime-Failed to write Seconds (Status=0x%08X)\n", (unsigned int)Result); + } + } + else + { + CFE_ES_WriteToSysLog("CFE_FS:SetTime-Failed to lseek time fields (Status=0x%08X)\n", (unsigned int)Result); + } + + return (Result); +} /* End of CFE_FS_SetTimestamp() */ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* */ +/* CFE_FS_ByteSwapCFEHeader() -- byte swap cFE file header structure */ +/* */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void CFE_FS_ByteSwapCFEHeader(CFE_FS_Header_t *Hdr) +{ + CFE_FS_ByteSwapUint32(&Hdr->ContentType); + CFE_FS_ByteSwapUint32(&Hdr->SubType); + CFE_FS_ByteSwapUint32(&Hdr->Length); + CFE_FS_ByteSwapUint32(&Hdr->SpacecraftID); + CFE_FS_ByteSwapUint32(&Hdr->ProcessorID); + CFE_FS_ByteSwapUint32(&Hdr->ApplicationID); + CFE_FS_ByteSwapUint32(&Hdr->TimeSeconds); + CFE_FS_ByteSwapUint32(&Hdr->TimeSubSeconds); + +} /* End of CFE_FS_ByteSwapCFEHeader() */ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* */ +/* CFE_FS_ByteSwapUint32() -- byte swap an uint32 */ +/* */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +void CFE_FS_ByteSwapUint32(uint32 *Uint32ToSwapPtr) +{ + int32 Temp = *Uint32ToSwapPtr; + char *InPtr = (char *)&Temp; + char *OutPtr = (char *)Uint32ToSwapPtr; + + OutPtr[0] = InPtr[3]; + OutPtr[1] = InPtr[2]; + OutPtr[2] = InPtr[1]; + OutPtr[3] = InPtr[0]; +} /* End of CFE_FS_ByteSwapUint32() */ + +/* +**--------------------------------------------------------------------------------------- +** Name: CFE_FS_ParseInputFileNameEx +** +** Purpose: This reads a file name from user input with extra logic to make more user friendly +** - absolute path is optional; assume default dir if missing +** - module extension is optional; append default for OS/platform if missing +**--------------------------------------------------------------------------------------- +*/ +int32 CFE_FS_ParseInputFileNameEx(char *OutputBuffer, const char *InputBuffer, size_t OutputBufSize, + size_t InputBufSize, const char *DefaultInput, const char *DefaultPath, + const char *DefaultExtension) +{ + int32 Status; + const char *InputPtr; + const char *ComponentPtr; + size_t ComponentLen; + char ComponentTerm; + size_t OutputLen; + size_t InputLen; + bool LastPathReached; + + /* The filename consists of a pathname, filename, and extension component. */ + enum + { + PROCESS_INIT, + PATHNAME_COMPONENT, + PATHNAME_SEPARATOR, + FILENAME_COMPONENT, + EXTENSION_SEPARATOR, + EXTENSION_COMPONENT, + END_COMPONENT + } Component; + + /* Sanity check buffer input */ + if (OutputBuffer == NULL || OutputBufSize == 0) + { + return CFE_FS_BAD_ARGUMENT; + } + + Status = CFE_FS_INVALID_PATH; + OutputLen = 0; + ComponentTerm = 0; + LastPathReached = false; + + /* If input buffer is not empty, then use it, otherwise use DefaultInput */ + if (InputBuffer != NULL && InputBufSize > 0 && InputBuffer[0] != 0) + { + InputPtr = InputBuffer; + InputLen = InputBufSize; + } + else if (DefaultInput != NULL) + { + /* This must be a normal null terminated string */ + InputPtr = DefaultInput; + InputLen = strlen(DefaultInput); + } + else + { + /* No input */ + InputPtr = NULL; + InputLen = 0; + } + + Component = PROCESS_INIT; + while (InputPtr != NULL && Component < END_COMPONENT) + { + /* Move to next component */ + if (Component == PATHNAME_SEPARATOR && !LastPathReached) + { + /* repeat until LastPathReached */ + Component = PATHNAME_COMPONENT; + } + else + { + ++Component; + } + + switch (Component) + { + case PATHNAME_COMPONENT: + /* path part ends with the last / char, which begins the filename */ + ComponentTerm = '/'; + ComponentPtr = memchr(InputPtr, ComponentTerm, InputLen); + if (ComponentPtr != NULL) + { + /* has path: use pathname from input, advance InputPtr to next part (filename) */ + ComponentLen = ComponentPtr - InputPtr; + ComponentPtr = InputPtr; + InputPtr += ComponentLen; + InputLen -= ComponentLen; + } + else + { + LastPathReached = true; + + /* no path: if no output at all yet, use default pathname, otherwise move on. */ + if (DefaultPath != NULL && OutputLen == 0) + { + ComponentLen = strlen(DefaultPath); + ComponentPtr = DefaultPath; + } + else + { + /* use no pathname at all */ + ComponentLen = 0; + ComponentPtr = NULL; + } + } + break; + + case FILENAME_COMPONENT: + /* filename ends with a . char, which begins the extension */ + ComponentTerm = '.'; + ComponentPtr = memchr(InputPtr, ComponentTerm, InputLen); + if (ComponentPtr != NULL) + { + /* has ext: use pathname from input, advance InputPtr to next part (extension) */ + ComponentLen = ComponentPtr - InputPtr; + ComponentPtr = InputPtr; + InputPtr += ComponentLen; + InputLen -= ComponentLen; + } + else + { + /* no ext: use remainder of input here - then use default extension for next part */ + ComponentLen = InputLen; + ComponentPtr = InputPtr; + if (DefaultExtension != NULL) + { + InputPtr = DefaultExtension; + InputLen = strlen(DefaultExtension); + } + else + { + /* Use no extension */ + InputPtr = NULL; + InputLen = 0; + } + } + + if (ComponentLen > 0 && *ComponentPtr != 0) + { + /* + * If the filename part is non-empty, then consider the conversion successful + * (note that extension is not really needed for an acceptable filename) + */ + Status = CFE_SUCCESS; + } + + break; + + case PATHNAME_SEPARATOR: + case EXTENSION_SEPARATOR: + /* Remove duplicate terminators that may have been in the input */ + while (OutputLen > 0 && OutputBuffer[OutputLen - 1] == ComponentTerm) + { + --OutputLen; + } + + ComponentLen = 1; + ComponentPtr = &ComponentTerm; + + /* advance past any separators in input to get to the next content */ + while (*InputPtr == ComponentTerm && InputLen > 0) + { + ++InputPtr; + --InputLen; + } + break; + + case EXTENSION_COMPONENT: + /* Intentional fall through to default case */ + + default: + /* Just consume the rest of input - + * should already be pointing to correct data */ + ComponentTerm = 0; + ComponentLen = InputLen; + ComponentPtr = InputPtr; + InputPtr = NULL; /* no more input */ + InputLen = 0; + break; + } + + /* Append component */ + while (ComponentLen > 0 && *ComponentPtr != 0) + { + OutputBuffer[OutputLen] = *ComponentPtr; + ++ComponentPtr; + ++OutputLen; + --ComponentLen; + + if (OutputLen >= OutputBufSize) + { + /* name is too long to fit in output buffer */ + Status = CFE_FS_FNAME_TOO_LONG; + InputPtr = NULL; /* no more input */ + InputLen = 0; + --OutputLen; /* back up one char for term */ + break; + } + } + } + + /* + * Always add a final terminating NUL char. + * + * Note that the loop above should never entirely fill + * buffer (length check includes extra char). + */ + OutputBuffer[OutputLen] = 0; + + return Status; +} + +/* +**--------------------------------------------------------------------------------------- +** Name: CFE_FS_ParseInputFileName +** +** Purpose: Simplified API for CFE_FS_ParseInputFileNameEx where input is always known to be +** a non-empty, null terminated string and the fixed-length input buffer not needed. +**--------------------------------------------------------------------------------------- +*/ +int32 CFE_FS_ParseInputFileName(char *OutputBuffer, const char *InputName, size_t OutputBufSize, + CFE_FS_FileCategory_t FileCategory) +{ + return CFE_FS_ParseInputFileNameEx(OutputBuffer, NULL, OutputBufSize, 0, InputName, + CFE_FS_GetDefaultMountPoint(FileCategory), + CFE_FS_GetDefaultExtension(FileCategory)); +} + +/* +** CFE_FS_ExtractFilenameFromPath - See API and header file for details +*/ +int32 CFE_FS_ExtractFilenameFromPath(const char *OriginalPath, char *FileNameOnly) +{ + uint32 i, j; + int StringLength; + int DirMarkIdx; + int32 ReturnCode; + + if (OriginalPath == NULL || FileNameOnly == NULL) + { + ReturnCode = CFE_FS_BAD_ARGUMENT; + } + else + { + + /* + ** Get the string length of the original file path + */ + StringLength = strlen(OriginalPath); + + /* + ** Extract the filename from the Path + */ + + /* + ** Find the last '/' Character + */ + DirMarkIdx = -1; + for (i = 0; i < StringLength; i++) + { + if (OriginalPath[i] == '/') + { + DirMarkIdx = i; + } + } + + /* + ** Verify the filename isn't too long + */ + if ((StringLength - (DirMarkIdx + 1)) < OS_MAX_PATH_LEN) + { + /* + ** Extract the filename portion + */ + if (DirMarkIdx > 0) + { + /* + ** Extract the filename portion + */ + j = 0; + for (i = DirMarkIdx + 1; i < StringLength; i++) + { + FileNameOnly[j] = OriginalPath[i]; + j++; + } + FileNameOnly[j] = '\0'; + + ReturnCode = CFE_SUCCESS; + } + else + { + ReturnCode = CFE_FS_INVALID_PATH; + } + } + else + { + ReturnCode = CFE_FS_FNAME_TOO_LONG; + } + } + + return (ReturnCode); +} + +/* +** CFE_FS_RunBackgroundFileDump - See API and header file for details +*/ +bool CFE_FS_RunBackgroundFileDump(uint32 ElapsedTime, void *Arg) +{ + CFE_FS_CurrentFileState_t * State; + CFE_FS_BackgroundFileDumpEntry_t *Curr; + CFE_FS_FileWriteMetaData_t * Meta; + int32 Status; + CFE_FS_Header_t FileHdr; + void * RecordPtr; + size_t RecordSize; + bool IsEOF; + + State = &CFE_FS_Global.FileDump.Current; + Curr = NULL; + IsEOF = false; + RecordPtr = NULL; + RecordSize = 0; + + State->Credit += (ElapsedTime * CFE_FS_BACKGROUND_CREDIT_PER_SECOND) / 1000; + if (State->Credit > CFE_FS_BACKGROUND_MAX_CREDIT) + { + State->Credit = CFE_FS_BACKGROUND_MAX_CREDIT; + } + + /* + * Lock shared data. + * Not strictly necessary as the "CompleteCount" is only updated + * by this task but this helps in case the access isn't atomic. + */ + CFE_FS_LockSharedData(__func__); + + if (CFE_FS_Global.FileDump.CompleteCount != CFE_FS_Global.FileDump.RequestCount) + { + Curr = &CFE_FS_Global.FileDump + .Entries[CFE_FS_Global.FileDump.CompleteCount & (CFE_FS_MAX_BACKGROUND_FILE_WRITES - 1)]; + } + + CFE_FS_UnlockSharedData(__func__); + + if (Curr == NULL) + { + return false; + } + + Meta = Curr->Meta; + + if (!OS_ObjectIdDefined(State->Fd) && Meta->IsPending) + { + /* First time processing this entry - open the file */ + Status = OS_OpenCreate(&State->Fd, Meta->FileName, OS_FILE_FLAG_CREATE | OS_FILE_FLAG_TRUNCATE, OS_WRITE_ONLY); + if (Status < 0) + { + State->Fd = OS_OBJECT_ID_UNDEFINED; + Meta->OnEvent(Meta, CFE_FS_FileWriteEvent_CREATE_ERROR, Status, 0, 0, 0); + } + else + { + CFE_FS_InitHeader(&FileHdr, Meta->Description, Meta->FileSubType); + + /* write the cFE header to the file */ + Status = CFE_FS_WriteHeader(State->Fd, &FileHdr); + if (Status != sizeof(CFE_FS_Header_t)) + { + OS_close(State->Fd); + State->Fd = OS_OBJECT_ID_UNDEFINED; + Meta->OnEvent(Meta, CFE_FS_FileWriteEvent_HEADER_WRITE_ERROR, Status, State->RecordNum, + sizeof(CFE_FS_Header_t), State->FileSize); + } + else + { + State->FileSize = sizeof(CFE_FS_Header_t); + State->Credit -= sizeof(CFE_FS_Header_t); + State->RecordNum = 0; + } + } + } + + while (OS_ObjectIdDefined(State->Fd) && State->Credit > 0 && !IsEOF) + { + /* + * Getter should return false on EOF (last record), true if more data is still waiting + */ + IsEOF = Meta->GetData(Meta, State->RecordNum, &RecordPtr, &RecordSize); + + /* + * if the getter outputs a record size of 0, this means there is no data for + * this entry, but the cycle keeps going (in case of "holes" or unused table entries + * in the database). + */ + if (RecordSize > 0) + { + State->Credit -= RecordSize; + + /* + * Now write to file + */ + Status = OS_write(State->Fd, RecordPtr, RecordSize); + + if (Status != RecordSize) + { + /* end the file early (cannot set "IsEOF" as this would cause the complete event to be generated too) */ + OS_close(State->Fd); + State->Fd = OS_OBJECT_ID_UNDEFINED; + + /* generate write error event */ + Meta->OnEvent(Meta, CFE_FS_FileWriteEvent_RECORD_WRITE_ERROR, Status, State->RecordNum, RecordSize, + State->FileSize); + break; + } + else + { + State->FileSize += RecordSize; + } + } + + ++State->RecordNum; + + } /* end if */ + + /* On normal EOF close the file and generate the complete event */ + if (IsEOF) + { + OS_close(State->Fd); + State->Fd = OS_OBJECT_ID_UNDEFINED; + + /* generate complete event */ + Meta->OnEvent(Meta, CFE_FS_FileWriteEvent_COMPLETE, CFE_SUCCESS, State->RecordNum, 0, State->FileSize); + } + + /* + * if the file is not open, consider this file complete, and advance the head position. + * (done this way so it also catches the case where the file failed to create, not just EOF) + */ + if (!OS_ObjectIdDefined(State->Fd)) + { + CFE_FS_LockSharedData(__func__); + + /* Wipe the entry structure, as it will be reused */ + memset(Curr, 0, sizeof(*Curr)); + ++CFE_FS_Global.FileDump.CompleteCount; + + /* Set the "IsPending" flag to false - this indicates that the originator may re-post now */ + Meta->IsPending = false; + + CFE_FS_UnlockSharedData(__func__); + + } /* end if */ + + return !IsEOF; +} + +/* +** CFE_FS_BackgroundFileDumpRequest - See API and header file for details +*/ +int32 CFE_FS_BackgroundFileDumpRequest(CFE_FS_FileWriteMetaData_t *Meta) +{ + CFE_FS_BackgroundFileDumpEntry_t *Curr; + int32 Status; + uint32 PendingRequestCount; + + /* Pre-validate inputs */ + if (Meta == NULL) + { + return CFE_FS_BAD_ARGUMENT; + } + + /* getter and event functions must be set */ + if (Meta->GetData == NULL || Meta->OnEvent == NULL) + { + return CFE_FS_BAD_ARGUMENT; + } + + /* filename cannot be empty */ + if (Meta->FileName[0] == 0) + { + return CFE_FS_INVALID_PATH; + } + + /* request must not already be pending */ + if (Meta->IsPending) + { + return CFE_STATUS_REQUEST_ALREADY_PENDING; + } + + CFE_FS_LockSharedData(__func__); + + PendingRequestCount = CFE_FS_Global.FileDump.RequestCount + 1; + + /* Check if queue is full before writing to tail position */ + if (PendingRequestCount == (CFE_FS_Global.FileDump.CompleteCount + CFE_FS_MAX_BACKGROUND_FILE_WRITES)) + { + Status = CFE_STATUS_REQUEST_ALREADY_PENDING; + } + else + { + Curr = &CFE_FS_Global.FileDump + .Entries[CFE_FS_Global.FileDump.RequestCount & (CFE_FS_MAX_BACKGROUND_FILE_WRITES - 1)]; + + /* + * store the meta object - note this retains the pointer that was submitted + * (caller must not reuse/change this object until request is completed) + */ + Curr->Meta = Meta; + + /* + * The "IsPending" Flag will be set true whenever while this is waiting in the request queue. + * It will be set false when the file is done. + * + * The requester can check this flag to determine if/when the request is complete + */ + Meta->IsPending = true; + + /* update tail position */ + CFE_FS_Global.FileDump.RequestCount = PendingRequestCount; + + Status = CFE_SUCCESS; + } + + CFE_FS_UnlockSharedData(__func__); + + if (Status == CFE_SUCCESS) + { + /* + * If successfully added to write queue, then wake the ES background task to get started. + * + * This may reduce the overall latency between request and completion (depending on other + * background task work). If this is the only pending job, this should get it started faster. + */ + CFE_ES_BackgroundWakeup(); + } + + return Status; +} + +/* +** CFE_FS_ExtractFilenameFromPath - See API and header file for details +*/ +bool CFE_FS_BackgroundFileDumpIsPending(const CFE_FS_FileWriteMetaData_t *Meta) +{ + if (Meta == NULL) + { + return false; + } + + return Meta->IsPending; +} + +/************************/ +/* End of File Comment */ +/************************/ diff --git a/modules/fs/fsw/src/cfe_fs_module_all.h b/modules/fs/fsw/src/cfe_fs_module_all.h new file mode 100644 index 000000000..9c2affb85 --- /dev/null +++ b/modules/fs/fsw/src/cfe_fs_module_all.h @@ -0,0 +1,41 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/** + * @file + * + * Encapsulates all FS module internal header files, as well + * as the public API from all other CFE core modules, OSAL, and PSP. + * + * This simplifies the set of include files that need to be put at the + * start of every source file. + */ + +#ifndef CFE_FS_MODULE_ALL_H +#define CFE_FS_MODULE_ALL_H + +/* +** Includes +*/ +#include "cfe.h" +#include "cfe_fs_priv.h" +#include "cfe_fs_core_internal.h" + +#endif /* CFE_FS_MODULE_ALL_H */ diff --git a/modules/fs/fsw/src/cfe_fs_priv.c b/modules/fs/fsw/src/cfe_fs_priv.c new file mode 100644 index 000000000..4344aaddc --- /dev/null +++ b/modules/fs/fsw/src/cfe_fs_priv.c @@ -0,0 +1,140 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/* +** File: cfe_fs_priv.c +** +** Purpose: cFE File Services (FS) library API Initialization +** +** Author: Alan Cudmore/NASA GSFC +** +** Notes: +** +*/ + +/* +** Required header files +*/ +#include "cfe_fs_module_all.h" + +#include + +/* +** Global data +** +*/ +CFE_FS_Global_t CFE_FS_Global; + +/****************************************************************************** +** Function: CFE_FS_EarlyInit() +** +** Purpose: +** Initialize the FS data structures before the cFE runs. +** +** Arguments: +** +** Notes: +** This function MUST be called before any FS API's are called. +** +** Return: +** CFE_SUCCESS +*/ +int32 CFE_FS_EarlyInit(void) +{ + int32 Stat; + + memset(&CFE_FS_Global, 0, sizeof(CFE_FS_Global)); + + Stat = OS_MutSemCreate(&CFE_FS_Global.SharedDataMutexId, "CFE_FS_SharedMutex", 0); + if (Stat != OS_SUCCESS) + { + CFE_ES_WriteToSysLog("FS Shared Data Mutex creation failed! RC=0x%08x\n", (unsigned int)Stat); + return Stat; + } /* end if */ + + return Stat; + +} /* end CFE_FS_EarlyInit */ + +/****************************************************************************** +** Function: CFE_FS_LockSharedData() +** +** Purpose: +** FS internal function to handle a semaphore take failure for the FS +** Data Mutex +** +** Arguments: +** FunctionName - the Function Name of the code that generated the error. +** +** Return: +** None +*/ +void CFE_FS_LockSharedData(const char *FunctionName) +{ + int32 Status; + CFE_ES_AppId_t AppId; + + Status = OS_MutSemTake(CFE_FS_Global.SharedDataMutexId); + if (Status != OS_SUCCESS) + { + CFE_ES_GetAppID(&AppId); + + CFE_ES_WriteToSysLog("FS SharedData Mutex Take Err Stat=0x%x,App=%lu,Function=%s\n", (unsigned int)Status, + CFE_RESOURCEID_TO_ULONG(AppId), FunctionName); + + } /* end if */ + + return; + +} /* end CFE_FS_LockSharedData */ + +/****************************************************************************** +** Function: CFE_FS_UnlockSharedData() +** +** Purpose: +** FS internal function to handle a semaphore give failure for the Shared +** Data Mutex +** +** Arguments: +** FunctionName - the Function containing the code that generated the error. +** +** Return: +** None +*/ +void CFE_FS_UnlockSharedData(const char *FunctionName) +{ + int32 Status; + CFE_ES_AppId_t AppId; + + Status = OS_MutSemGive(CFE_FS_Global.SharedDataMutexId); + if (Status != OS_SUCCESS) + { + CFE_ES_GetAppID(&AppId); + CFE_ES_WriteToSysLog("FS SharedData Mutex Give Err Stat=0x%x,App=%lu,Function=%s\n", (unsigned int)Status, + CFE_RESOURCEID_TO_ULONG(AppId), FunctionName); + + } /* end if */ + return; + +} /* end CFE_FS_UnlockSharedData */ + +/************************/ +/* End of File Comment */ +/************************/ diff --git a/modules/fs/fsw/src/cfe_fs_priv.h b/modules/fs/fsw/src/cfe_fs_priv.h new file mode 100644 index 000000000..3979d98ec --- /dev/null +++ b/modules/fs/fsw/src/cfe_fs_priv.h @@ -0,0 +1,155 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/** + * @file + * + * Purpose: + * This header file contains prototypes for private functions and type + * definitions for FS internal use. + * + * Author: A. Cudmore/NASA GSFC + * + */ + +#ifndef CFE_FS_PRIV_H +#define CFE_FS_PRIV_H + +/* +** Includes +*/ +#include "common_types.h" +#include "cfe_fs_api_typedefs.h" +#include "cfe_es_api_typedefs.h" + +/* +** Macro Definitions +*/ + +/* + * Max Number of file write requests that can be queued + * + * This needs to be a power of two to simplify the masking/wraparound (bitwise AND). + */ +#define CFE_FS_MAX_BACKGROUND_FILE_WRITES 4 + +/* + * Background file credit accumulation rate + * + * The background file writer will limit the total bytes written over time. This + * controls the amount of "credit" (bytes that can be written) per second + * of elapsed time. + * + * This permits a file writing rate of up to 10kbytes/sec. + */ +#define CFE_FS_BACKGROUND_CREDIT_PER_SECOND 10000 + +/* + * Maximum credit that the background write task can accumulate + * + * The background file writer will limit the total bytes written over time, and + * will accumulate credit against this limit while no writes are in progress. + * This is an upper cap on the amount of credit that can be accumulated. + * + * Without this limit, after a long period of inactivity without any file + * writes, a large credit would essentially bypass the rate limiting for + * the next file write command(s) once they are issued. + */ +#define CFE_FS_BACKGROUND_MAX_CREDIT 10000 + +/* +** Type Definitions +*/ + +/* + * Background file dump entry structure + * + * This structure is stored in global memory and keeps the state + * of the file dump from one iteration to the next. + */ +typedef struct +{ + CFE_ES_AppId_t RequestorAppId; + CFE_FS_FileWriteMetaData_t *Meta; +} CFE_FS_BackgroundFileDumpEntry_t; + +typedef struct +{ + osal_id_t Fd; + int32 Credit; + uint32 RecordNum; + size_t FileSize; +} CFE_FS_CurrentFileState_t; + +/** + * \brief Background file dump queue structure + * + * This structure is stored in global memory and keeps the state + * of the file dump from one iteration to the next. + * + * Normally when idle the "RequestCount" and "CompleteCount" are the + * same value. When an application requests a background file dump, + * the "RequestCount" is incremented accordingly, and when the background + * job finishes, the "CompleteCount" is incremented accordingly. + */ +typedef struct +{ + uint32 RequestCount; /**< Total Number of background file writes requested */ + uint32 CompleteCount; /**< Total Number of background file writes completed */ + + /** + * Data related to each background file write request + */ + CFE_FS_BackgroundFileDumpEntry_t Entries[CFE_FS_MAX_BACKGROUND_FILE_WRITES]; + + /** + * Persistent storage for the current file write + * (reused for each file) + */ + CFE_FS_CurrentFileState_t Current; + +} CFE_FS_BackgroundFileDumpState_t; + +/****************************************************************************** +** Typedef: CFE_FS_Global_t +** +** Purpose: +** This structure contains the FS global variables. +*/ +typedef struct +{ + osal_id_t SharedDataMutexId; + + CFE_FS_BackgroundFileDumpState_t FileDump; + +} CFE_FS_Global_t; + +extern CFE_FS_Global_t CFE_FS_Global; + +/* +** FS Function Prototypes +*/ + +extern void CFE_FS_LockSharedData(const char *FunctionName); +extern void CFE_FS_UnlockSharedData(const char *FunctionName); +extern void CFE_FS_ByteSwapCFEHeader(CFE_FS_Header_t *Hdr); +extern void CFE_FS_ByteSwapUint32(uint32 *Uint32ToSwapPtr); + +#endif /* CFE_FS_PRIV_H */