diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ae9885..fd88f77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,8 @@ include_directories(fsw/src) set(APP_SRC_FILES fsw/src/bp_app.c + fsw/src/bp_cmd.c + fsw/src/bp_dispatch.c fsw/src/bp_flow.c fsw/src/bp_cla_bundle_io.c fsw/src/bp_storage.c diff --git a/config/default_bp_fcncodes.h b/config/default_bp_fcncodes.h index f41652f..70c6b89 100644 --- a/config/default_bp_fcncodes.h +++ b/config/default_bp_fcncodes.h @@ -36,7 +36,7 @@ /* BP_CMD_MID */ #define BP_NOOP_CC 0 -#define BP_RESET_CC 1 +#define BP_RESET_APP_CC 1 #define BP_RELOAD_FLOW_TABLE_CC 2 #define BP_ENABLE_FLOW_CC 3 #define BP_DISABLE_FLOW_CC 4 @@ -49,9 +49,9 @@ #define BP_DISABLE_OVERRIDE_PRIORITY_CC 11 /* BP_SEND_HK_MID */ -#define BP_SEND_APP_CC 0 -#define BP_SEND_ENABLED_CC 1 -#define BP_SEND_DISABLED_CC 2 +#define BP_SEND_APP_TLM_CC 0 +#define BP_SEND_ENABLED_FLOW_TLM_CC 1 +#define BP_SEND_DISABLED_FLOW_TLM_CC 2 /* BP_WAKEUP_MID */ #define BP_WAKEUP_CC 0 diff --git a/config/default_bp_msgstruct.h b/config/default_bp_msgstruct.h index ff8f36c..00c08aa 100644 --- a/config/default_bp_msgstruct.h +++ b/config/default_bp_msgstruct.h @@ -223,4 +223,9 @@ typedef struct CFE_MSG_CommandHeader_t CommandHeader; } BP_SendDisabledFlowTlmCmd_t; +typedef struct +{ + CFE_MSG_CommandHeader_t CommandHeader; +} BP_ProcessWakeupCmd_t; + #endif /* BP_MSG_H */ diff --git a/fsw/src/bp_app.c b/fsw/src/bp_app.c index 30f704d..5de4561 100644 --- a/fsw/src/bp_app.c +++ b/fsw/src/bp_app.c @@ -28,6 +28,7 @@ #include "cfe.h" #include "bp_msgids.h" #include "bp_storecfg.h" +#include "bp_tlmcfg.h" #include "bp_global.h" #include "bp_app.h" #include "bp_platform_cfg.h" @@ -35,6 +36,7 @@ #include "bp_eventids.h" #include "bp_version.h" #include "bp_flow.h" +#include "bp_dispatch.h" #include "bp_cla_bundle_io.h" #include "bplib_routing.h" @@ -46,65 +48,6 @@ * Local Functions ************************************************/ -/*----------------------------------------------- - * A helper/wrapper that handles stats commands that operate per-flow - * This is used in conjunction with BP_ForEachFlow() which invokes it for each flow handle - *-----------------------------------------------*/ -static void BP_SendStatsMsgPerFlow(BP_FlowHandle_t fh, void *Arg) -{ - bool want_enabled_flows = *((bool *)Arg); - - /* - * this may send either the enabled flows or the disabled flows, - * depending on which the caller asked for via the arg - */ - if (want_enabled_flows == BP_FlowIsEnabled(fh)) - { - BP_FlowGetStats(fh, &BP_GlobalData.FlowHkPkt.FlowStats); - CFE_SB_TimeStampMsg(CFE_MSG_PTR(BP_GlobalData.FlowHkPkt.TelemetryHeader)); - - /* transmit msg is always "best effort", it does not fail unless misconfigured */ - CFE_SB_TransmitMsg(CFE_MSG_PTR(BP_GlobalData.FlowHkPkt.TelemetryHeader), true); - } -} - -/*----------------------------------------------- - * A helper/wrapper that handles the flow stats reset command - * This is used in conjunction with BP_ForEachFlow() which invokes it for each flow handle - *-----------------------------------------------*/ -static void BP_DoPerFlowStatReset(BP_FlowHandle_t fh, void *Arg) -{ - BP_FlowClearStats(fh); -} - -/*----------------------------------------------- - * A helper/wrapper that disables all flows - * This is used in conjunction with BP_ForEachFlow() which invokes it for each flow handle - *-----------------------------------------------*/ -static void BP_DoPerFlowDisable(BP_FlowHandle_t fh, void *Arg) -{ - BP_FlowDisable(fh); -} - -/*----------------------------------------------- - * A helper/wrapper that handles the flow enable/disable command - * This is used in conjunction with BP_ForEachFlow() which invokes it for each flow handle - * The objective is to recompute the 32-bit mask value for TLM. - *-----------------------------------------------*/ -static void BP_RebuildBitmaskPerFlow(BP_FlowHandle_t fh, void *Arg) -{ - uint32 *Mask = (uint32 *)Arg; - uint32 Idx; - - if (BP_FlowIsEnabled(fh)) - { - /* This is called only for handles which are known good, and BP_FlowIsEnabled() - * confirmed that the flow handle is good, so "ToIndex" will never fail */ - BP_FlowHandle_ToIndex(fh, &Idx); - *Mask |= 1 << Idx; - } -} - static CFE_Status_t BP_SetupLibrary(void) { /* Initialize BP Library */ @@ -219,7 +162,7 @@ static CFE_Status_t AppInit(void) return status; /* Initialize the "EnableMask" in TLM from initial config */ - BP_ForEachFlow(BP_RebuildBitmaskPerFlow, &BP_GlobalData.HkPkt.Payload.EnableMask); + BP_DoRebuildFlowBitmask(); /* Application startup event message */ CFE_EVS_SendEvent(BP_INIT_APP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP App Version %d.%d.%d.%d: Initialized", @@ -228,571 +171,6 @@ static CFE_Status_t AppInit(void) return CFE_SUCCESS; } -/*----------------------------------------------- - * PktLenCheck - *-----------------------------------------------*/ -static CFE_Status_t BP_PktLenCheck(const CFE_SB_Buffer_t *MsgBuf, size_t ExpLen) -{ - size_t act_len; - - if (CFE_MSG_GetSize(&MsgBuf->Msg, &act_len) != CFE_SUCCESS || act_len != ExpLen) - { - CFE_EVS_SendEvent(BP_INVALID_LEN_ERR_EID, CFE_EVS_EventType_ERROR, - "Invalid length in packet, exp = %lu, act = %lu", (unsigned long)ExpLen, - (unsigned long)act_len); - return CFE_STATUS_WRONG_MSG_LENGTH; - } - - return CFE_SUCCESS; -} - -/*----------------------------------------------- - * NoopCmd - *-----------------------------------------------*/ -CFE_Status_t BP_NoopCmd(const BP_NoopCmd_t *cmd) -{ - /* Issue Event */ - CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, - "No operation command received for BP version %d.%d.%d.%d", BP_MAJOR_VERSION, BP_MINOR_VERSION, - BP_REVISION, BP_MISSION_REV); - - return CFE_SUCCESS; -} - -/*----------------------------------------------- - * ResetAppCmd - *-----------------------------------------------*/ -CFE_Status_t BP_ResetAppCmd(const BP_ResetAppCmd_t *cmd) -{ - /* Clear Command Counters */ - BP_GlobalData.HkPkt.Payload.ValidCmdCnt = 0; - BP_GlobalData.HkPkt.Payload.InvalidCmdCnt = 0; - - /* Clear Custom Telemetry */ - BP_ClearCustomTlm(&BP_GlobalData.HkPkt.Payload.CustomTlm); - - BP_ForEachFlow(BP_DoPerFlowStatReset, NULL); - - /* Issue Event */ - CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Statistics: Cleared"); - - return CFE_SUCCESS; -} - -/*----------------------------------------------- - * ReloadFlowTableCmd - *-----------------------------------------------*/ -CFE_Status_t BP_ReloadFlowTableCmd(const BP_ReloadFlowTableCmd_t *cmd) -{ - CFE_Status_t status; - uint32 EnableMask; - - /* Disable All Flows */ - BP_ForEachFlow(BP_DoPerFlowDisable, NULL); - - /* Reopen All Flows and Issue Event */ - status = BP_FlowLoad(NULL); - if (status == CFE_SUCCESS) - { - CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Tables: Reloaded"); - } - - /* Initialize the "EnableMask" in TLM from reloaded config */ - EnableMask = 0; - BP_ForEachFlow(BP_RebuildBitmaskPerFlow, &EnableMask); - BP_GlobalData.HkPkt.Payload.EnableMask = EnableMask; - - return status; -} - -/*----------------------------------------------- - * EnableFlowCmd - *-----------------------------------------------*/ -CFE_Status_t BP_EnableFlowCmd(const BP_EnableFlowCmd_t *cmd) -{ - BP_FlowHandle_t flow; - CFE_Status_t status; - uint32 EnableMask; - - /* Get Flow */ - flow = BP_FlowGetHandle(cmd->Payload.Name); - - /* Enable Flow and Issue Event */ - status = BP_FlowEnable(flow); - if (status == CFE_SUCCESS) - { - CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Flow %s: Enabled", BP_FlowGetName(flow)); - } - - /* Rebuild the "EnableMask" in HkPkt */ - EnableMask = 0; - BP_ForEachFlow(BP_RebuildBitmaskPerFlow, &EnableMask); - BP_GlobalData.HkPkt.Payload.EnableMask = EnableMask; - - return status; -} - -/*----------------------------------------------- - * DisableFlowCmd - *-----------------------------------------------*/ -CFE_Status_t BP_DisableFlowCmd(const BP_DisableFlowCmd_t *cmd) -{ - BP_FlowHandle_t flow; - CFE_Status_t status; - uint32 EnableMask; - - /* Get Flow */ - flow = BP_FlowGetHandle(cmd->Payload.Name); - - /* Disable Flow and Issue Event */ - status = BP_FlowDisable(flow); - if (status == CFE_SUCCESS) - { - CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Flow %s: Disabled", BP_FlowGetName(flow)); - } - - /* Rebuild the "EnableMask" in HkPkt */ - EnableMask = 0; - BP_ForEachFlow(BP_RebuildBitmaskPerFlow, &EnableMask); - BP_GlobalData.HkPkt.Payload.EnableMask = EnableMask; - - return status; -} - -/*----------------------------------------------- - * FlushFlowCmd - *-----------------------------------------------*/ -CFE_Status_t BP_FlushFlowCmd(const BP_FlushFlowCmd_t *cmd) -{ - BP_FlowHandle_t flow; - CFE_Status_t status; - - /* Get Flow */ - flow = BP_FlowGetHandle(cmd->Payload.Name); - - /* Flush Flow and Issue Event */ - status = BP_FlowFlush(flow); - if (status == CFE_SUCCESS) - { - CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Flow %s: Flushed", BP_FlowGetName(flow)); - } - - return status; -} - -/*----------------------------------------------- - * PauseFlowCmd - *-----------------------------------------------*/ -CFE_Status_t BP_PauseFlowCmd(const BP_PauseFlowCmd_t *cmd) -{ - BP_FlowHandle_t flow; - CFE_Status_t status; - - /* Get Flow */ - flow = BP_FlowGetHandle(cmd->Payload.Name); - - /* Pause Flow and Issue Event */ - status = BP_FlowPause(flow); - if (status == CFE_SUCCESS) - { - CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Flow %s: Paused", BP_FlowGetName(flow)); - } - - return status; -} - -/*----------------------------------------------- - * ResumeFlowCmd - *-----------------------------------------------*/ -CFE_Status_t BP_ResumeFlowCmd(const BP_ResumeFlowCmd_t *cmd) -{ - BP_FlowHandle_t flow; - CFE_Status_t status; - - /* Get Flow */ - flow = BP_FlowGetHandle(cmd->Payload.Name); - - /* Resume Flow and Issue Event */ - status = BP_FlowResume(flow); - if (status == CFE_SUCCESS) - { - CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Flow %s: Resumed", BP_FlowGetName(flow)); - } - - return status; -} - -/*----------------------------------------------- - * OverrideTimeoutCmd - *-----------------------------------------------*/ -CFE_Status_t BP_OverrideTimeoutCmd(const BP_OverrideTimeoutCmd_t *cmd) -{ - BP_FlowHandle_t flow; - CFE_Status_t status; - - /* Get Flow */ - flow = BP_FlowGetHandle(cmd->Payload.Name); - - /* Override Timeout and Issue Event */ - status = BP_FlowSetTimeout(flow, (int)cmd->Payload.Timeout); - if (status == CFE_SUCCESS) - { - CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Flow %s: Timeout Overridden %d", - BP_FlowGetName(flow), (int)cmd->Payload.Timeout); - } - - return status; -} - -/*----------------------------------------------- - * DisableOverrideTimeoutCmd - *-----------------------------------------------*/ -CFE_Status_t BP_DisableOverrideTimeoutCmd(const BP_DisableOverrideTimeoutCmd_t *cmd) -{ - BP_FlowHandle_t flow; - CFE_Status_t status; - - /* Get Flow */ - flow = BP_FlowGetHandle(cmd->Payload.Name); - - /* Disable Override and Issue Event */ - status = BP_FlowRevertTimeout(flow); - if (status == CFE_SUCCESS) - { - CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Flow %s: Timeout Override Disabled", - BP_FlowGetName(flow)); - } - - return status; -} - -/*----------------------------------------------- - * OverridePriorityCmd - *-----------------------------------------------*/ -CFE_Status_t BP_OverridePriorityCmd(const BP_OverridePriorityCmd_t *cmd) -{ - BP_FlowHandle_t flow; - CFE_Status_t status; - - /* Get Flow */ - flow = BP_FlowGetHandle(cmd->Payload.Name); - - /* Override Priority and Issue Event */ - status = BP_FlowSetPriority(flow, (int)cmd->Payload.Priority); - if (status == CFE_SUCCESS) - { - CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Flow %s: Priority Overridden %d", - BP_FlowGetName(flow), (int)cmd->Payload.Priority); - } - - return status; -} - -/*----------------------------------------------- - * DisableOverridePriorityCmd - *-----------------------------------------------*/ -CFE_Status_t BP_DisableOverridePriorityCmd(const BP_DisableOverridePriorityCmd_t *cmd) -{ - BP_FlowHandle_t flow; - CFE_Status_t status; - - /* Get Flow */ - flow = BP_FlowGetHandle(cmd->Payload.Name); - - /* Disable Override and Issue Event */ - status = BP_FlowRevertPriority(flow); - if (status == CFE_SUCCESS) - { - CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Flow %s: Priority Override Disabled", - BP_FlowGetName(flow)); - } - - return status; -} - -/*----------------------------------------------- - * BP_SendAppTlmCmd - *-----------------------------------------------*/ -CFE_Status_t BP_SendAppTlmCmd(const BP_SendAppTlmCmd_t *cmd) -{ - bp_sval_t mem_use; - int status; - - /* Populate Memory Usage Statistics */ - status = bplib_query_integer(BP_GlobalData.RouteTbl, BP_INVALID_HANDLE, bplib_variable_mem_current_use, &mem_use); - if (status == BP_SUCCESS) - { - BP_GlobalData.HkPkt.Payload.MemInUse = mem_use; - } - else - { - BP_GlobalData.HkPkt.Payload.MemInUse = 0; - } - - status = bplib_query_integer(BP_GlobalData.RouteTbl, BP_INVALID_HANDLE, bplib_variable_mem_high_use, &mem_use); - if (status == BP_SUCCESS) - { - BP_GlobalData.HkPkt.Payload.MemHighWater = mem_use; - } - else - { - BP_GlobalData.HkPkt.Payload.MemHighWater = 0; - } - - /* Populate Custom Flash Statistics */ - BP_PopulateCustomTlm(&BP_GlobalData.HkPkt.Payload.CustomTlm); - - /* Send Application Housekeeping Packet */ - CFE_SB_TimeStampMsg(CFE_MSG_PTR(BP_GlobalData.HkPkt.TelemetryHeader)); - CFE_SB_TransmitMsg(CFE_MSG_PTR(BP_GlobalData.HkPkt.TelemetryHeader), true); - - return CFE_SUCCESS; -} - -/*----------------------------------------------- - * BP_SendEnabledFlowTlmCmd - *-----------------------------------------------*/ -CFE_Status_t BP_SendEnabledFlowTlmCmd(const BP_SendEnabledFlowTlmCmd_t *cmd) -{ - bool want_enabled_flows = true; - - /* Populate and Send Flow Housekeeping Packets */ - BP_ForEachFlow(BP_SendStatsMsgPerFlow, &want_enabled_flows); - - return CFE_SUCCESS; -} - -/*----------------------------------------------- - * BP_SendDisabledFlowTlmCmd - *-----------------------------------------------*/ -CFE_Status_t BP_SendDisabledFlowTlmCmd(const BP_SendDisabledFlowTlmCmd_t *cmd) -{ - bool want_enabled_flows = false; - - /* Populate and Send Flow Housekeeping Packets */ - BP_ForEachFlow(BP_SendStatsMsgPerFlow, &want_enabled_flows); - - return CFE_SUCCESS; -} - -/*----------------------------------------------- - * BP_ProcessWakeupCmd - *-----------------------------------------------*/ -CFE_Status_t BP_ProcessWakeupCmd(const CFE_MSG_CommandHeader_t *cmd) -{ - /* no options, just process the flows */ - BP_FlowProcess(); - bplib_route_periodic_maintenance(BP_GlobalData.RouteTbl); - - return CFE_SUCCESS; -} - -/*----------------------------------------------- - * ProcessCmd - *-----------------------------------------------*/ -static CFE_Status_t ProcessCmd(const CFE_SB_Buffer_t *MsgBufPtr) -{ - CFE_MSG_FcnCode_t cmd_code; - CFE_Status_t cmd_result; - - cmd_result = CFE_MSG_GetFcnCode(&MsgBufPtr->Msg, &cmd_code); - if (cmd_result != CFE_SUCCESS) - { - return cmd_result; - } - - /* Invoke specific command handler */ - switch (cmd_code) - { - case BP_NOOP_CC: - cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_NoopCmd_t)); - if (cmd_result == CFE_SUCCESS) - { - cmd_result = BP_NoopCmd((const BP_NoopCmd_t *)MsgBufPtr); - } - break; - case BP_RESET_CC: - cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_ResetAppCmd_t)); - if (cmd_result == CFE_SUCCESS) - { - cmd_result = BP_ResetAppCmd((const BP_ResetAppCmd_t *)MsgBufPtr); - } - break; - case BP_RELOAD_FLOW_TABLE_CC: - cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_ReloadFlowTableCmd_t)); - if (cmd_result == CFE_SUCCESS) - { - cmd_result = BP_ReloadFlowTableCmd((const BP_ReloadFlowTableCmd_t *)MsgBufPtr); - } - break; - case BP_ENABLE_FLOW_CC: - cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_EnableFlowCmd_t)); - if (cmd_result == CFE_SUCCESS) - { - cmd_result = BP_EnableFlowCmd((const BP_EnableFlowCmd_t *)MsgBufPtr); - } - break; - case BP_DISABLE_FLOW_CC: - cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_DisableFlowCmd_t)); - if (cmd_result == CFE_SUCCESS) - { - cmd_result = BP_DisableFlowCmd((const BP_DisableFlowCmd_t *)MsgBufPtr); - } - break; - case BP_FLUSH_FLOW_CC: - cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_FlushFlowCmd_t)); - if (cmd_result == CFE_SUCCESS) - { - cmd_result = BP_FlushFlowCmd((const BP_FlushFlowCmd_t *)MsgBufPtr); - } - break; - case BP_PAUSE_FLOW_CC: - cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_PauseFlowCmd_t)); - if (cmd_result == CFE_SUCCESS) - { - cmd_result = BP_PauseFlowCmd((const BP_PauseFlowCmd_t *)MsgBufPtr); - } - break; - case BP_RESUME_FLOW_CC: - cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_ResumeFlowCmd_t)); - if (cmd_result == CFE_SUCCESS) - { - cmd_result = BP_ResumeFlowCmd((const BP_ResumeFlowCmd_t *)MsgBufPtr); - } - break; - case BP_OVERRIDE_TIMEOUT_CC: - cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_OverrideTimeoutCmd_t)); - if (cmd_result == CFE_SUCCESS) - { - cmd_result = BP_OverrideTimeoutCmd((const BP_OverrideTimeoutCmd_t *)MsgBufPtr); - } - break; - case BP_DISABLE_OVERRIDE_TIMEOUT_CC: - cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_DisableOverrideTimeoutCmd_t)); - if (cmd_result == CFE_SUCCESS) - { - cmd_result = BP_DisableOverrideTimeoutCmd((const BP_DisableOverrideTimeoutCmd_t *)MsgBufPtr); - } - break; - case BP_OVERRIDE_PRIORITY_CC: - cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_OverridePriorityCmd_t)); - if (cmd_result == CFE_SUCCESS) - { - cmd_result = BP_OverridePriorityCmd((const BP_OverridePriorityCmd_t *)MsgBufPtr); - } - break; - case BP_DISABLE_OVERRIDE_PRIORITY_CC: - cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_DisableOverridePriorityCmd_t)); - if (cmd_result == CFE_SUCCESS) - { - cmd_result = BP_DisableOverridePriorityCmd((const BP_DisableOverridePriorityCmd_t *)MsgBufPtr); - } - break; - default: - cmd_result = CFE_STATUS_BAD_COMMAND_CODE; - break; - } - - /* Update Housekeeping Statistics */ - if (cmd_result == CFE_SUCCESS) - BP_GlobalData.HkPkt.Payload.ValidCmdCnt++; - else - BP_GlobalData.HkPkt.Payload.InvalidCmdCnt++; - - return cmd_result; -} - -/*----------------------------------------------- - * ProcessHk - *-----------------------------------------------*/ -static CFE_Status_t ProcessHk(const CFE_SB_Buffer_t *MessagePtr) -{ - CFE_Status_t status; - CFE_MSG_FcnCode_t cmd_code; - - status = CFE_MSG_GetFcnCode(&MessagePtr->Msg, &cmd_code); - if (status != CFE_SUCCESS) - { - return status; - } - - if (cmd_code == BP_SEND_APP_CC) - { - status = BP_SendAppTlmCmd((const BP_SendAppTlmCmd_t *)MessagePtr); - } - else if (cmd_code == BP_SEND_ENABLED_CC) - { - status = BP_SendEnabledFlowTlmCmd((const BP_SendEnabledFlowTlmCmd_t *)MessagePtr); - } - else if (cmd_code == BP_SEND_DISABLED_CC) - { - status = BP_SendDisabledFlowTlmCmd((const BP_SendDisabledFlowTlmCmd_t *)MessagePtr); - } - else - { - status = CFE_STATUS_BAD_COMMAND_CODE; - } - - return status; -} - -/*----------------------------------------------- - * ProcessFlows - *-----------------------------------------------*/ -static CFE_Status_t ProcessFlows(const CFE_SB_Buffer_t *MessagePtr) -{ - CFE_Status_t status; - CFE_MSG_FcnCode_t cmd_code; - - status = CFE_MSG_GetFcnCode(&MessagePtr->Msg, &cmd_code); - if (status != CFE_SUCCESS) - { - return status; - } - - if (cmd_code == BP_WAKEUP_PROCESS_CC) - { - status = BP_ProcessWakeupCmd((const CFE_MSG_CommandHeader_t *)MessagePtr); - } - else - { - status = CFE_STATUS_BAD_COMMAND_CODE; - } - - return status; -} - -/*----------------------------------------------- - * ProcessPkt - *-----------------------------------------------*/ -CFE_Status_t BP_ProcessPkt(const CFE_SB_Buffer_t *MessagePtr) -{ - CFE_SB_MsgId_t MessageID; - CFE_Status_t Status; - - Status = CFE_MSG_GetMsgId(&MessagePtr->Msg, &MessageID); - if (Status == CFE_SUCCESS) - { - switch (CFE_SB_MsgIdToValue(MessageID)) - { - case BP_CMD_MID: - Status = ProcessCmd(MessagePtr); - break; - case BP_SEND_HK_MID: - Status = ProcessHk(MessagePtr); - break; - case BP_WAKEUP_MID: - Status = ProcessFlows(MessagePtr); - break; - default: - Status = CFE_STATUS_UNKNOWN_MSG_ID; - break; - } - } - - return Status; -} - /************************************************ * Exported Functions ************************************************/ @@ -824,7 +202,7 @@ void BP_AppMain(void) /* Handle Result */ if (sb_rcv_result == CFE_SUCCESS) { - BP_ProcessPkt(MsgBuf); + BP_AppPipe(MsgBuf); } else if (sb_rcv_result != CFE_SB_TIME_OUT) { diff --git a/fsw/src/bp_app.h b/fsw/src/bp_app.h index bf6c03d..531e12e 100644 --- a/fsw/src/bp_app.h +++ b/fsw/src/bp_app.h @@ -24,30 +24,6 @@ #include "cfe_error.h" #include "bp_msg.h" -/*----------------------------------------------- - * Command Handlers - *-----------------------------------------------*/ -CFE_Status_t BP_NoopCmd(const BP_NoopCmd_t *cmd); -CFE_Status_t BP_ResetAppCmd(const BP_ResetAppCmd_t *cmd); -CFE_Status_t BP_ReloadFlowTableCmd(const BP_ReloadFlowTableCmd_t *cmd); -CFE_Status_t BP_EnableFlowCmd(const BP_EnableFlowCmd_t *cmd); -CFE_Status_t BP_DisableFlowCmd(const BP_DisableFlowCmd_t *cmd); -CFE_Status_t BP_FlushFlowCmd(const BP_FlushFlowCmd_t *cmd); -CFE_Status_t BP_PauseFlowCmd(const BP_PauseFlowCmd_t *cmd); -CFE_Status_t BP_ResumeFlowCmd(const BP_ResumeFlowCmd_t *cmd); -CFE_Status_t BP_OverrideTimeoutCmd(const BP_OverrideTimeoutCmd_t *cmd); -CFE_Status_t BP_DisableOverrideTimeoutCmd(const BP_DisableOverrideTimeoutCmd_t *cmd); -CFE_Status_t BP_OverridePriorityCmd(const BP_OverridePriorityCmd_t *cmd); -CFE_Status_t BP_DisableOverridePriorityCmd(const BP_DisableOverridePriorityCmd_t *cmd); - -CFE_Status_t BP_SendAppTlmCmd(const BP_SendAppTlmCmd_t *cmd); -CFE_Status_t BP_SendEnabledFlowTlmCmd(const BP_SendEnabledFlowTlmCmd_t *cmd); -CFE_Status_t BP_SendDisabledFlowTlmCmd(const BP_SendDisabledFlowTlmCmd_t *cmd); - -CFE_Status_t BP_ProcessWakeupCmd(const CFE_MSG_CommandHeader_t *cmd); - -CFE_Status_t BP_ProcessPkt(const CFE_SB_Buffer_t *MessagePtr); - /************************************************ * Exported Functions ************************************************/ diff --git a/fsw/src/bp_cmd.c b/fsw/src/bp_cmd.c new file mode 100644 index 0000000..6a92276 --- /dev/null +++ b/fsw/src/bp_cmd.c @@ -0,0 +1,424 @@ +/* + * NASA Docket No. GSC-18,587-1 and identified as “The Bundle Protocol Core Flight + * System Application (BP) v6.5” + * + * Copyright © 2020 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. + * + */ + +/************************************************ + * Includes + ************************************************/ + +#include + +#include "bp_cmd.h" +#include "bp_storecfg.h" +#include "bp_tlmcfg.h" +#include "bp_global.h" +#include "bp_app.h" +#include "bp_platform_cfg.h" +#include "bp_msg.h" +#include "bp_eventids.h" +#include "bp_version.h" +#include "bp_flow.h" +#include "bp_cla_bundle_io.h" +#include "bplib_routing.h" + +#include "cfe.h" + +/************************************************ + * File Data + ************************************************/ + +/************************************************ + * Local Functions + ************************************************/ + +/*----------------------------------------------- + * A helper/wrapper that handles stats commands that operate per-flow + * This is used in conjunction with BP_ForEachFlow() which invokes it for each flow handle + *-----------------------------------------------*/ +static void BP_SendStatsMsgPerFlow(BP_FlowHandle_t fh, void *Arg) +{ + bool want_enabled_flows = *((bool *)Arg); + + /* + * this may send either the enabled flows or the disabled flows, + * depending on which the caller asked for via the arg + */ + if (want_enabled_flows == BP_FlowIsEnabled(fh)) + { + BP_FlowGetStats(fh, &BP_GlobalData.FlowHkPkt.FlowStats); + CFE_SB_TimeStampMsg(CFE_MSG_PTR(BP_GlobalData.FlowHkPkt.TelemetryHeader)); + + /* transmit msg is always "best effort", it does not fail unless misconfigured */ + CFE_SB_TransmitMsg(CFE_MSG_PTR(BP_GlobalData.FlowHkPkt.TelemetryHeader), true); + } +} + +/*----------------------------------------------- + * A helper/wrapper that handles the flow stats reset command + * This is used in conjunction with BP_ForEachFlow() which invokes it for each flow handle + *-----------------------------------------------*/ +static void BP_DoPerFlowStatReset(BP_FlowHandle_t fh, void *Arg) +{ + BP_FlowClearStats(fh); +} + +/*----------------------------------------------- + * A helper/wrapper that disables all flows + * This is used in conjunction with BP_ForEachFlow() which invokes it for each flow handle + *-----------------------------------------------*/ +static void BP_DoPerFlowDisable(BP_FlowHandle_t fh, void *Arg) +{ + BP_FlowDisable(fh); +} + +/************************************************ + * Exported Functions + ************************************************/ + +/*----------------------------------------------- + * NoopCmd + *-----------------------------------------------*/ +CFE_Status_t BP_NoopCmd(const BP_NoopCmd_t *cmd) +{ + /* Issue Event */ + CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, + "No operation command received for BP version %d.%d.%d.%d", BP_MAJOR_VERSION, BP_MINOR_VERSION, + BP_REVISION, BP_MISSION_REV); + + return CFE_SUCCESS; +} + +/*----------------------------------------------- + * ResetAppCmd + *-----------------------------------------------*/ +CFE_Status_t BP_ResetAppCmd(const BP_ResetAppCmd_t *cmd) +{ + /* Clear Command Counters */ + BP_GlobalData.HkPkt.Payload.ValidCmdCnt = 0; + BP_GlobalData.HkPkt.Payload.InvalidCmdCnt = 0; + + /* Clear Custom Telemetry */ + BP_ClearCustomTlm(&BP_GlobalData.HkPkt.Payload.CustomTlm); + + BP_ForEachFlow(BP_DoPerFlowStatReset, NULL); + + /* Issue Event */ + CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Statistics: Cleared"); + + return CFE_SUCCESS; +} + +/*----------------------------------------------- + * ReloadFlowTableCmd + *-----------------------------------------------*/ +CFE_Status_t BP_ReloadFlowTableCmd(const BP_ReloadFlowTableCmd_t *cmd) +{ + CFE_Status_t status; + + /* Disable All Flows */ + BP_ForEachFlow(BP_DoPerFlowDisable, NULL); + + /* Reopen All Flows and Issue Event */ + status = BP_FlowLoad(NULL); + if (status == CFE_SUCCESS) + { + CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Tables: Reloaded"); + } + + /* Initialize the "EnableMask" in TLM from reloaded config */ + BP_DoRebuildFlowBitmask(); + + return status; +} + +/*----------------------------------------------- + * EnableFlowCmd + *-----------------------------------------------*/ +CFE_Status_t BP_EnableFlowCmd(const BP_EnableFlowCmd_t *cmd) +{ + BP_FlowHandle_t flow; + CFE_Status_t status; + + /* Get Flow */ + flow = BP_FlowGetHandle(cmd->Payload.Name); + + /* Enable Flow and Issue Event */ + status = BP_FlowEnable(flow); + if (status == CFE_SUCCESS) + { + CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Flow %s: Enabled", BP_FlowGetName(flow)); + } + + /* Rebuild the "EnableMask" in HkPkt */ + BP_DoRebuildFlowBitmask(); + + return status; +} + +/*----------------------------------------------- + * DisableFlowCmd + *-----------------------------------------------*/ +CFE_Status_t BP_DisableFlowCmd(const BP_DisableFlowCmd_t *cmd) +{ + BP_FlowHandle_t flow; + CFE_Status_t status; + + /* Get Flow */ + flow = BP_FlowGetHandle(cmd->Payload.Name); + + /* Disable Flow and Issue Event */ + status = BP_FlowDisable(flow); + if (status == CFE_SUCCESS) + { + CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Flow %s: Disabled", BP_FlowGetName(flow)); + } + + /* Rebuild the "EnableMask" in HkPkt */ + BP_DoRebuildFlowBitmask(); + + return status; +} + +/*----------------------------------------------- + * FlushFlowCmd + *-----------------------------------------------*/ +CFE_Status_t BP_FlushFlowCmd(const BP_FlushFlowCmd_t *cmd) +{ + BP_FlowHandle_t flow; + CFE_Status_t status; + + /* Get Flow */ + flow = BP_FlowGetHandle(cmd->Payload.Name); + + /* Flush Flow and Issue Event */ + status = BP_FlowFlush(flow); + if (status == CFE_SUCCESS) + { + CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Flow %s: Flushed", BP_FlowGetName(flow)); + } + + return status; +} + +/*----------------------------------------------- + * PauseFlowCmd + *-----------------------------------------------*/ +CFE_Status_t BP_PauseFlowCmd(const BP_PauseFlowCmd_t *cmd) +{ + BP_FlowHandle_t flow; + CFE_Status_t status; + + /* Get Flow */ + flow = BP_FlowGetHandle(cmd->Payload.Name); + + /* Pause Flow and Issue Event */ + status = BP_FlowPause(flow); + if (status == CFE_SUCCESS) + { + CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Flow %s: Paused", BP_FlowGetName(flow)); + } + + return status; +} + +/*----------------------------------------------- + * ResumeFlowCmd + *-----------------------------------------------*/ +CFE_Status_t BP_ResumeFlowCmd(const BP_ResumeFlowCmd_t *cmd) +{ + BP_FlowHandle_t flow; + CFE_Status_t status; + + /* Get Flow */ + flow = BP_FlowGetHandle(cmd->Payload.Name); + + /* Resume Flow and Issue Event */ + status = BP_FlowResume(flow); + if (status == CFE_SUCCESS) + { + CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Flow %s: Resumed", BP_FlowGetName(flow)); + } + + return status; +} + +/*----------------------------------------------- + * OverrideTimeoutCmd + *-----------------------------------------------*/ +CFE_Status_t BP_OverrideTimeoutCmd(const BP_OverrideTimeoutCmd_t *cmd) +{ + BP_FlowHandle_t flow; + CFE_Status_t status; + + /* Get Flow */ + flow = BP_FlowGetHandle(cmd->Payload.Name); + + /* Override Timeout and Issue Event */ + status = BP_FlowSetTimeout(flow, (int)cmd->Payload.Timeout); + if (status == CFE_SUCCESS) + { + CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Flow %s: Timeout Overridden %d", + BP_FlowGetName(flow), (int)cmd->Payload.Timeout); + } + + return status; +} + +/*----------------------------------------------- + * DisableOverrideTimeoutCmd + *-----------------------------------------------*/ +CFE_Status_t BP_DisableOverrideTimeoutCmd(const BP_DisableOverrideTimeoutCmd_t *cmd) +{ + BP_FlowHandle_t flow; + CFE_Status_t status; + + /* Get Flow */ + flow = BP_FlowGetHandle(cmd->Payload.Name); + + /* Disable Override and Issue Event */ + status = BP_FlowRevertTimeout(flow); + if (status == CFE_SUCCESS) + { + CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Flow %s: Timeout Override Disabled", + BP_FlowGetName(flow)); + } + + return status; +} + +/*----------------------------------------------- + * OverridePriorityCmd + *-----------------------------------------------*/ +CFE_Status_t BP_OverridePriorityCmd(const BP_OverridePriorityCmd_t *cmd) +{ + BP_FlowHandle_t flow; + CFE_Status_t status; + + /* Get Flow */ + flow = BP_FlowGetHandle(cmd->Payload.Name); + + /* Override Priority and Issue Event */ + status = BP_FlowSetPriority(flow, (int)cmd->Payload.Priority); + if (status == CFE_SUCCESS) + { + CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Flow %s: Priority Overridden %d", + BP_FlowGetName(flow), (int)cmd->Payload.Priority); + } + + return status; +} + +/*----------------------------------------------- + * DisableOverridePriorityCmd + *-----------------------------------------------*/ +CFE_Status_t BP_DisableOverridePriorityCmd(const BP_DisableOverridePriorityCmd_t *cmd) +{ + BP_FlowHandle_t flow; + CFE_Status_t status; + + /* Get Flow */ + flow = BP_FlowGetHandle(cmd->Payload.Name); + + /* Disable Override and Issue Event */ + status = BP_FlowRevertPriority(flow); + if (status == CFE_SUCCESS) + { + CFE_EVS_SendEvent(BP_INFO_EID, CFE_EVS_EventType_INFORMATION, "BP Flow %s: Priority Override Disabled", + BP_FlowGetName(flow)); + } + + return status; +} + +/*----------------------------------------------- + * BP_SendAppTlmCmd + *-----------------------------------------------*/ +CFE_Status_t BP_SendAppTlmCmd(const BP_SendAppTlmCmd_t *cmd) +{ + bp_sval_t mem_use; + int status; + + /* Populate Memory Usage Statistics */ + status = bplib_query_integer(BP_GlobalData.RouteTbl, BP_INVALID_HANDLE, bplib_variable_mem_current_use, &mem_use); + if (status == BP_SUCCESS) + { + BP_GlobalData.HkPkt.Payload.MemInUse = mem_use; + } + else + { + BP_GlobalData.HkPkt.Payload.MemInUse = 0; + } + + status = bplib_query_integer(BP_GlobalData.RouteTbl, BP_INVALID_HANDLE, bplib_variable_mem_high_use, &mem_use); + if (status == BP_SUCCESS) + { + BP_GlobalData.HkPkt.Payload.MemHighWater = mem_use; + } + else + { + BP_GlobalData.HkPkt.Payload.MemHighWater = 0; + } + + /* Populate Custom Flash Statistics */ + BP_PopulateCustomTlm(&BP_GlobalData.HkPkt.Payload.CustomTlm); + + /* Send Application Housekeeping Packet */ + CFE_SB_TimeStampMsg(CFE_MSG_PTR(BP_GlobalData.HkPkt.TelemetryHeader)); + CFE_SB_TransmitMsg(CFE_MSG_PTR(BP_GlobalData.HkPkt.TelemetryHeader), true); + + return CFE_SUCCESS; +} + +/*----------------------------------------------- + * BP_SendEnabledFlowTlmCmd + *-----------------------------------------------*/ +CFE_Status_t BP_SendEnabledFlowTlmCmd(const BP_SendEnabledFlowTlmCmd_t *cmd) +{ + bool want_enabled_flows = true; + + /* Populate and Send Flow Housekeeping Packets */ + BP_ForEachFlow(BP_SendStatsMsgPerFlow, &want_enabled_flows); + + return CFE_SUCCESS; +} + +/*----------------------------------------------- + * BP_SendDisabledFlowTlmCmd + *-----------------------------------------------*/ +CFE_Status_t BP_SendDisabledFlowTlmCmd(const BP_SendDisabledFlowTlmCmd_t *cmd) +{ + bool want_enabled_flows = false; + + /* Populate and Send Flow Housekeeping Packets */ + BP_ForEachFlow(BP_SendStatsMsgPerFlow, &want_enabled_flows); + + return CFE_SUCCESS; +} + +/*----------------------------------------------- + * BP_ProcessWakeupCmd + *-----------------------------------------------*/ +CFE_Status_t BP_ProcessWakeupCmd(const BP_ProcessWakeupCmd_t *cmd) +{ + /* no options, just process the flows */ + BP_FlowProcess(); + bplib_route_periodic_maintenance(BP_GlobalData.RouteTbl); + + return CFE_SUCCESS; +} diff --git a/fsw/src/bp_cmd.h b/fsw/src/bp_cmd.h new file mode 100644 index 0000000..6b28cb6 --- /dev/null +++ b/fsw/src/bp_cmd.h @@ -0,0 +1,52 @@ +/* + * NASA Docket No. GSC-18,587-1 and identified as “The Bundle Protocol Core Flight + * System Application (BP) v6.5” + * + * Copyright © 2020 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. + * + */ + +#ifndef BP_CMD_H +#define BP_CMD_H + +/************************************************ + * Includes + ************************************************/ + +#include "cfe_error.h" +#include "bp_msg.h" + +/************************************************ + * Exported Functions + ************************************************/ + +CFE_Status_t BP_NoopCmd(const BP_NoopCmd_t *cmd); +CFE_Status_t BP_ResetAppCmd(const BP_ResetAppCmd_t *cmd); +CFE_Status_t BP_ReloadFlowTableCmd(const BP_ReloadFlowTableCmd_t *cmd); +CFE_Status_t BP_EnableFlowCmd(const BP_EnableFlowCmd_t *cmd); +CFE_Status_t BP_DisableFlowCmd(const BP_DisableFlowCmd_t *cmd); +CFE_Status_t BP_FlushFlowCmd(const BP_FlushFlowCmd_t *cmd); +CFE_Status_t BP_PauseFlowCmd(const BP_PauseFlowCmd_t *cmd); +CFE_Status_t BP_ResumeFlowCmd(const BP_ResumeFlowCmd_t *cmd); +CFE_Status_t BP_OverrideTimeoutCmd(const BP_OverrideTimeoutCmd_t *cmd); +CFE_Status_t BP_DisableOverrideTimeoutCmd(const BP_DisableOverrideTimeoutCmd_t *cmd); +CFE_Status_t BP_OverridePriorityCmd(const BP_OverridePriorityCmd_t *cmd); +CFE_Status_t BP_DisableOverridePriorityCmd(const BP_DisableOverridePriorityCmd_t *cmd); +CFE_Status_t BP_SendAppTlmCmd(const BP_SendAppTlmCmd_t *cmd); +CFE_Status_t BP_SendEnabledFlowTlmCmd(const BP_SendEnabledFlowTlmCmd_t *cmd); +CFE_Status_t BP_SendDisabledFlowTlmCmd(const BP_SendDisabledFlowTlmCmd_t *cmd); +CFE_Status_t BP_ProcessWakeupCmd(const BP_ProcessWakeupCmd_t *cmd); + +#endif diff --git a/fsw/src/bp_dispatch.c b/fsw/src/bp_dispatch.c new file mode 100644 index 0000000..435a7da --- /dev/null +++ b/fsw/src/bp_dispatch.c @@ -0,0 +1,260 @@ +/* + * NASA Docket No. GSC-18,587-1 and identified as “The Bundle Protocol Core Flight + * System Application (BP) v6.5” + * + * Copyright © 2020 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. + * + */ + +/************************************************ + * Includes + ************************************************/ + +#include + +#include "bp_dispatch.h" +#include "bp_cmd.h" +#include "bp_global.h" +#include "bp_platform_cfg.h" +#include "bp_msg.h" +#include "bp_msgids.h" +#include "bp_eventids.h" + +#include "cfe.h" + +/*----------------------------------------------- + * PktLenCheck + *-----------------------------------------------*/ +static CFE_Status_t BP_PktLenCheck(const CFE_SB_Buffer_t *MsgBuf, size_t ExpLen) +{ + size_t act_len; + + if (CFE_MSG_GetSize(&MsgBuf->Msg, &act_len) != CFE_SUCCESS || act_len != ExpLen) + { + CFE_EVS_SendEvent(BP_INVALID_LEN_ERR_EID, CFE_EVS_EventType_ERROR, + "Invalid length in packet, exp = %lu, act = %lu", (unsigned long)ExpLen, + (unsigned long)act_len); + return CFE_STATUS_WRONG_MSG_LENGTH; + } + + return CFE_SUCCESS; +} + +/*----------------------------------------------- + * ProcessCmd + *-----------------------------------------------*/ +static CFE_Status_t ProcessCmd(const CFE_SB_Buffer_t *MsgBufPtr) +{ + CFE_MSG_FcnCode_t cmd_code; + CFE_Status_t cmd_result; + + cmd_result = CFE_MSG_GetFcnCode(&MsgBufPtr->Msg, &cmd_code); + if (cmd_result != CFE_SUCCESS) + { + return cmd_result; + } + + /* Invoke specific command handler */ + switch (cmd_code) + { + case BP_NOOP_CC: + cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_NoopCmd_t)); + if (cmd_result == CFE_SUCCESS) + { + cmd_result = BP_NoopCmd((const BP_NoopCmd_t *)MsgBufPtr); + } + break; + case BP_RESET_APP_CC: + cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_ResetAppCmd_t)); + if (cmd_result == CFE_SUCCESS) + { + cmd_result = BP_ResetAppCmd((const BP_ResetAppCmd_t *)MsgBufPtr); + } + break; + case BP_RELOAD_FLOW_TABLE_CC: + cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_ReloadFlowTableCmd_t)); + if (cmd_result == CFE_SUCCESS) + { + cmd_result = BP_ReloadFlowTableCmd((const BP_ReloadFlowTableCmd_t *)MsgBufPtr); + } + break; + case BP_ENABLE_FLOW_CC: + cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_EnableFlowCmd_t)); + if (cmd_result == CFE_SUCCESS) + { + cmd_result = BP_EnableFlowCmd((const BP_EnableFlowCmd_t *)MsgBufPtr); + } + break; + case BP_DISABLE_FLOW_CC: + cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_DisableFlowCmd_t)); + if (cmd_result == CFE_SUCCESS) + { + cmd_result = BP_DisableFlowCmd((const BP_DisableFlowCmd_t *)MsgBufPtr); + } + break; + case BP_FLUSH_FLOW_CC: + cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_FlushFlowCmd_t)); + if (cmd_result == CFE_SUCCESS) + { + cmd_result = BP_FlushFlowCmd((const BP_FlushFlowCmd_t *)MsgBufPtr); + } + break; + case BP_PAUSE_FLOW_CC: + cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_PauseFlowCmd_t)); + if (cmd_result == CFE_SUCCESS) + { + cmd_result = BP_PauseFlowCmd((const BP_PauseFlowCmd_t *)MsgBufPtr); + } + break; + case BP_RESUME_FLOW_CC: + cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_ResumeFlowCmd_t)); + if (cmd_result == CFE_SUCCESS) + { + cmd_result = BP_ResumeFlowCmd((const BP_ResumeFlowCmd_t *)MsgBufPtr); + } + break; + case BP_OVERRIDE_TIMEOUT_CC: + cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_OverrideTimeoutCmd_t)); + if (cmd_result == CFE_SUCCESS) + { + cmd_result = BP_OverrideTimeoutCmd((const BP_OverrideTimeoutCmd_t *)MsgBufPtr); + } + break; + case BP_DISABLE_OVERRIDE_TIMEOUT_CC: + cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_DisableOverrideTimeoutCmd_t)); + if (cmd_result == CFE_SUCCESS) + { + cmd_result = BP_DisableOverrideTimeoutCmd((const BP_DisableOverrideTimeoutCmd_t *)MsgBufPtr); + } + break; + case BP_OVERRIDE_PRIORITY_CC: + cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_OverridePriorityCmd_t)); + if (cmd_result == CFE_SUCCESS) + { + cmd_result = BP_OverridePriorityCmd((const BP_OverridePriorityCmd_t *)MsgBufPtr); + } + break; + case BP_DISABLE_OVERRIDE_PRIORITY_CC: + cmd_result = BP_PktLenCheck(MsgBufPtr, sizeof(BP_DisableOverridePriorityCmd_t)); + if (cmd_result == CFE_SUCCESS) + { + cmd_result = BP_DisableOverridePriorityCmd((const BP_DisableOverridePriorityCmd_t *)MsgBufPtr); + } + break; + default: + cmd_result = CFE_STATUS_BAD_COMMAND_CODE; + break; + } + + /* Update Housekeeping Statistics */ + if (cmd_result == CFE_SUCCESS) + BP_GlobalData.HkPkt.Payload.ValidCmdCnt++; + else + BP_GlobalData.HkPkt.Payload.InvalidCmdCnt++; + + return cmd_result; +} + +/*----------------------------------------------- + * ProcessHk + *-----------------------------------------------*/ +static CFE_Status_t ProcessHk(const CFE_SB_Buffer_t *MessagePtr) +{ + CFE_Status_t status; + CFE_MSG_FcnCode_t cmd_code; + + status = CFE_MSG_GetFcnCode(&MessagePtr->Msg, &cmd_code); + if (status != CFE_SUCCESS) + { + return status; + } + + if (cmd_code == BP_SEND_APP_TLM_CC) + { + status = BP_SendAppTlmCmd((const BP_SendAppTlmCmd_t *)MessagePtr); + } + else if (cmd_code == BP_SEND_ENABLED_FLOW_TLM_CC) + { + status = BP_SendEnabledFlowTlmCmd((const BP_SendEnabledFlowTlmCmd_t *)MessagePtr); + } + else if (cmd_code == BP_SEND_DISABLED_FLOW_TLM_CC) + { + status = BP_SendDisabledFlowTlmCmd((const BP_SendDisabledFlowTlmCmd_t *)MessagePtr); + } + else + { + status = CFE_STATUS_BAD_COMMAND_CODE; + } + + return status; +} + +/*----------------------------------------------- + * ProcessFlows + *-----------------------------------------------*/ +static CFE_Status_t ProcessFlows(const CFE_SB_Buffer_t *MessagePtr) +{ + CFE_Status_t status; + CFE_MSG_FcnCode_t cmd_code; + + status = CFE_MSG_GetFcnCode(&MessagePtr->Msg, &cmd_code); + if (status != CFE_SUCCESS) + { + return status; + } + + if (cmd_code == BP_WAKEUP_PROCESS_CC) + { + status = BP_ProcessWakeupCmd((const BP_ProcessWakeupCmd_t *)MessagePtr); + } + else + { + status = CFE_STATUS_BAD_COMMAND_CODE; + } + + return status; +} + +/*----------------------------------------------- + * ProcessPkt + *-----------------------------------------------*/ +void BP_AppPipe(const CFE_SB_Buffer_t *BufPtr) +{ + CFE_SB_MsgId_t MsgId; + CFE_Status_t Status; + + Status = CFE_MSG_GetMsgId(&BufPtr->Msg, &MsgId); + if (Status == CFE_SUCCESS) + { + switch (CFE_SB_MsgIdToValue(MsgId)) + { + case BP_CMD_MID: + ProcessCmd(BufPtr); + break; + case BP_SEND_HK_MID: + ProcessHk(BufPtr); + break; + case BP_WAKEUP_MID: + ProcessFlows(BufPtr); + break; + default: + ++BP_GlobalData.HkPkt.Payload.InvalidCmdCnt; + CFE_EVS_SendEvent(BP_INVALID_MID_ERR_EID, CFE_EVS_EventType_ERROR, + "BP: Invalid Msg ID Rcvd 0x%x", + (unsigned int)CFE_SB_MsgIdToValue(MsgId)); + break; + } + } +} diff --git a/fsw/src/bp_dispatch.h b/fsw/src/bp_dispatch.h new file mode 100644 index 0000000..54c52e3 --- /dev/null +++ b/fsw/src/bp_dispatch.h @@ -0,0 +1,53 @@ +/* + * NASA Docket No. GSC-18,587-1 and identified as “The Bundle Protocol Core Flight + * System Application (BP) v6.5” + * + * Copyright © 2020 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 + * Specification for the CFS Bundle Protocol (BP) routines that + * handle command processing + */ +#ifndef BP_DISPATCH_H +#define BP_DISPATCH_H + +/************************************************************************* + * Includes + ************************************************************************/ +#include "cfe_sb_api_typedefs.h" + +/************************************************************************* + * Exported Functions + ************************************************************************/ + +/** + * \brief Process a command pipe message + * + * \par Description + * Processes a single software bus command pipe message. Checks + * the message and command IDs and calls the appropriate routine + * to handle the message. + * + * \par Assumptions, External Events, and Notes: + * None + * + * \param[in] BufPtr Pointer to Software Bus buffer + */ +void BP_AppPipe(const CFE_SB_Buffer_t *BufPtr); + +#endif diff --git a/fsw/src/bp_flow.c b/fsw/src/bp_flow.c index 2f667b6..d7dfce4 100644 --- a/fsw/src/bp_flow.c +++ b/fsw/src/bp_flow.c @@ -97,6 +97,25 @@ static inline bool BP_FlowEntryIsMatch(const BP_FlowCtrlEntry_t *FlowPtr, BP_Flo return (FlowPtr != NULL && CFE_RESOURCEID_TEST_EQUAL(FlowPtr->Handle, Flow)); } +/*----------------------------------------------- + * A helper/wrapper that handles the flow enable/disable command + * This is used in conjunction with BP_ForEachFlow() which invokes it for each flow handle + * The objective is to recompute the 32-bit mask value for TLM. + *-----------------------------------------------*/ +static void BP_RebuildBitmaskPerFlow(BP_FlowHandle_t fh, void *Arg) +{ + uint32 *Mask = (uint32 *)Arg; + uint32 Idx; + + if (BP_FlowIsEnabled(fh)) + { + /* This is called only for handles which are known good, and BP_FlowIsEnabled() + * confirmed that the flow handle is good, so "ToIndex" will never fail */ + BP_FlowHandle_ToIndex(fh, &Idx); + *Mask |= 1 << Idx; + } +} + /*---------------------------------------------------------------- * * Application-scope internal function @@ -548,8 +567,8 @@ int32 BP_FlowInit(const char *AppName) int32 BP_FlowLoad(const char *FlowTableFileName) { int32 cfe_status; - BP_FlowTable_t *StagedConfig; - BP_FlowTblEntry_t *StagingEntryPtr; + BP_FlowTable_t * StagedConfig; + BP_FlowTblEntry_t * StagingEntryPtr; BP_FlowCtrlEntry_t *FlowPtr; CFE_ResourceId_t PendingFlowHandle; CFE_TBL_Info_t tbl_info; @@ -768,7 +787,7 @@ int32 BP_FlowEnable(BP_FlowHandle_t Flow) /* Subscribe valid entry */ CFE_SB_Qos_t Quality = {FlowPtr->Config.PktTbl[i].Priority, FlowPtr->Config.PktTbl[i].Reliability}; int32 cfe_status = CFE_SB_SubscribeEx(FlowPtr->Config.PktTbl[i].StreamId, FlowPtr->DataPipe, Quality, - FlowPtr->Config.PktTbl[i].BuffLim); + FlowPtr->Config.PktTbl[i].BuffLim); if (cfe_status != CFE_SUCCESS) { /* Report Failures and Continue (do not mark status) */ @@ -1362,3 +1381,19 @@ void BP_ForEachFlow(void (*Func)(BP_FlowHandle_t, void *Arg), void *Arg) } } } + +/*---------------------------------------------------------------- + * + * Application-scope internal function + * See description in header file for argument/return detail + * + *-----------------------------------------------------------------*/ +void BP_DoRebuildFlowBitmask(void) +{ + uint32 EnableMask; + + /* Initialize the "EnableMask" in TLM from reloaded config */ + EnableMask = 0; + BP_ForEachFlow(BP_RebuildBitmaskPerFlow, &EnableMask); + BP_GlobalData.HkPkt.Payload.EnableMask = EnableMask; +} diff --git a/fsw/src/bp_flow.h b/fsw/src/bp_flow.h index 58a128d..51026cb 100644 --- a/fsw/src/bp_flow.h +++ b/fsw/src/bp_flow.h @@ -77,7 +77,7 @@ typedef struct bool Healthy; BP_StorageHandle_t StorageHandle; BP_FlowPriority_t COS; /* class of service */ - bp_socket_t *BPS; /* bundle protocol library socket */ + bp_socket_t * BPS; /* bundle protocol library socket */ CFE_SB_PipeId_t DataPipe; CFE_SB_Buffer_t *CurrentSbMsgInPtr; @@ -244,4 +244,12 @@ int32 BP_FlowHandle_ToIndex(BP_FlowHandle_t Flow, uint32 *Idx); *----------------------------------------------*/ void BP_ForEachFlow(void (*Func)(BP_FlowHandle_t, void *Arg), void *Arg); +/*----------------------------------------------- + * BP_DoRebuildFlowBitmask + * + * Recomputes the value for the "EnableMask" field in the HK TLM. + * Should be invoked every time a flow state changes to keep TLM in sync. + *----------------------------------------------*/ +void BP_DoRebuildFlowBitmask(void); + #endif /* BP_FLOW_H */