From a42133568b29f46d67319d4ff29cd65508b9c56f Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Fri, 27 Oct 2023 13:10:55 -0400 Subject: [PATCH] Fix #149, add decode hooks Add an intermediate step during ingest to allow the buffer to be decoded prior to sending to SB. Initial implementation is just a pass-through, thus matching existing behavior. --- CMakeLists.txt | 1 + fsw/src/ci_lab_app.c | 59 ++++++++-------- fsw/src/ci_lab_app.h | 3 +- fsw/src/ci_lab_decode.h | 35 ++++++++++ fsw/src/ci_lab_passthru_decode.c | 114 +++++++++++++++++++++++++++++++ 5 files changed, 182 insertions(+), 30 deletions(-) create mode 100644 fsw/src/ci_lab_decode.h create mode 100644 fsw/src/ci_lab_passthru_decode.c diff --git a/CMakeLists.txt b/CMakeLists.txt index bbcfb05..cb5b320 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ set(APP_SRC_FILES fsw/src/ci_lab_app.c fsw/src/ci_lab_cmds.c fsw/src/ci_lab_dispatch.c + fsw/src/ci_lab_passthru_decode.c ) # Create the app module diff --git a/fsw/src/ci_lab_app.c b/fsw/src/ci_lab_app.c index 4b7000a..3a5cdcd 100644 --- a/fsw/src/ci_lab_app.c +++ b/fsw/src/ci_lab_app.c @@ -29,6 +29,7 @@ #include "ci_lab_perfids.h" #include "ci_lab_msgids.h" #include "ci_lab_version.h" +#include "ci_lab_decode.h" /* ** CI Global Data @@ -200,53 +201,53 @@ void CI_LAB_ResetCounters_Internal(void) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **/ void CI_LAB_ReadUpLink(void) { - int i; - CFE_Status_t status; - uint8 * bytes; + int i; + int32 OsStatus; + + CFE_Status_t CfeStatus; + CFE_SB_Buffer_t *SBBufPtr; for (i = 0; i <= 10; i++) { - if (CI_LAB_Global.NextIngestBufPtr == NULL) + if (CI_LAB_Global.NetBufPtr == NULL) { - CI_LAB_Global.NextIngestBufPtr = CFE_SB_AllocateMessageBuffer(CI_LAB_MAX_INGEST); - if (CI_LAB_Global.NextIngestBufPtr == NULL) - { - CFE_EVS_SendEvent(CI_LAB_INGEST_ALLOC_ERR_EID, CFE_EVS_EventType_ERROR, - "CI: L%d, buffer allocation failed\n", __LINE__); - break; - } + CI_LAB_GetInputBuffer(&CI_LAB_Global.NetBufPtr, &CI_LAB_Global.NetBufSize); } - status = OS_SocketRecvFrom(CI_LAB_Global.SocketID, CI_LAB_Global.NextIngestBufPtr, CI_LAB_MAX_INGEST, - &CI_LAB_Global.SocketAddress, OS_CHECK); - if (status >= (int32)sizeof(CFE_MSG_CommandHeader_t) && status <= ((int32)CI_LAB_MAX_INGEST)) + if (CI_LAB_Global.NetBufPtr == NULL) + { + break; + } + + OsStatus = OS_SocketRecvFrom(CI_LAB_Global.SocketID, CI_LAB_Global.NetBufPtr, CI_LAB_Global.NetBufSize, + &CI_LAB_Global.SocketAddress, OS_CHECK); + if (OsStatus > 0) { CFE_ES_PerfLogEntry(CI_LAB_SOCKET_RCV_PERF_ID); - CI_LAB_Global.HkTlm.Payload.IngestPackets++; - status = CFE_SB_TransmitBuffer(CI_LAB_Global.NextIngestBufPtr, false); + CfeStatus = CI_LAB_DecodeInputMessage(CI_LAB_Global.NetBufPtr, OsStatus, &SBBufPtr); + if (CfeStatus != CFE_SUCCESS) + { + CI_LAB_Global.HkTlm.Payload.IngestErrors++; + } + else + { + CI_LAB_Global.HkTlm.Payload.IngestPackets++; + CfeStatus = CFE_SB_TransmitBuffer(SBBufPtr, false); + } CFE_ES_PerfLogExit(CI_LAB_SOCKET_RCV_PERF_ID); - if (status == CFE_SUCCESS) + if (CfeStatus == CFE_SUCCESS) { /* Set NULL so a new buffer will be obtained next time around */ - CI_LAB_Global.NextIngestBufPtr = NULL; + CI_LAB_Global.NetBufPtr = NULL; + CI_LAB_Global.NetBufSize = 0; } else { CFE_EVS_SendEvent(CI_LAB_INGEST_SEND_ERR_EID, CFE_EVS_EventType_ERROR, - "CI: L%d, CFE_SB_TransmitBuffer() failed, status=%d\n", __LINE__, (int)status); + "CI_LAB: Ingest failed, status=%d\n", (int)CfeStatus); } } - else if (status > 0) - { - /* bad size, report as ingest error */ - CI_LAB_Global.HkTlm.Payload.IngestErrors++; - - bytes = CI_LAB_Global.NextIngestBufPtr->Msg.Byte; - CFE_EVS_SendEvent(CI_LAB_INGEST_LEN_ERR_EID, CFE_EVS_EventType_ERROR, - "CI: L%d, cmd %0x%0x %0x%0x dropped, bad length=%d\n", __LINE__, bytes[0], bytes[1], - bytes[2], bytes[3], (int)status); - } else { break; /* no (more) messages */ diff --git a/fsw/src/ci_lab_app.h b/fsw/src/ci_lab_app.h index 0b2500f..cb1510e 100644 --- a/fsw/src/ci_lab_app.h +++ b/fsw/src/ci_lab_app.h @@ -59,7 +59,8 @@ typedef struct CI_LAB_HkTlm_t HkTlm; - CFE_SB_Buffer_t *NextIngestBufPtr; + void * NetBufPtr; + size_t NetBufSize; } CI_LAB_GlobalData_t; diff --git a/fsw/src/ci_lab_decode.h b/fsw/src/ci_lab_decode.h new file mode 100644 index 0000000..db4b2ff --- /dev/null +++ b/fsw/src/ci_lab_decode.h @@ -0,0 +1,35 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 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 + * This is the dispatch hdr file for the Command Ingest lab application. + */ +#ifndef CI_LAB_DECODE_H +#define CI_LAB_DECODE_H + +/* +** Required header files... +*/ +#include "common_types.h" +#include "cfe_sb_api_typedefs.h" + +CFE_Status_t CI_LAB_GetInputBuffer(void **BufferOut, size_t *SizeOut); +CFE_Status_t CI_LAB_DecodeInputMessage(void *SourceBuffer, size_t SourceSize, CFE_SB_Buffer_t **DestBufferOut); + +#endif diff --git a/fsw/src/ci_lab_passthru_decode.c b/fsw/src/ci_lab_passthru_decode.c new file mode 100644 index 0000000..05d41e8 --- /dev/null +++ b/fsw/src/ci_lab_passthru_decode.c @@ -0,0 +1,114 @@ +/************************************************************************ + * NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes” + * + * Copyright (c) 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 + * This file contains the source code for the Command Ingest task. + */ + +/* +** Include Files: +*/ +#include "cfe.h" + +#include "ci_lab_app.h" +#include "ci_lab_perfids.h" +#include "ci_lab_msgids.h" +#include "ci_lab_decode.h" + +/* + * --------------------------------------- + * In a "passthrough" configuration - the data from the network + * is expected to be a direct instance of the CFE_MSG_Message_t base, + * and thus something can be sent directly to SB. + * + * Instead of using an intermediate buffer, just get a buffer from + * SB and put it directly in there. This reduces copying. + * --------------------------------------- + */ +CFE_Status_t CI_LAB_GetInputBuffer(void **BufferOut, size_t *SizeOut) +{ + CFE_SB_Buffer_t *IngestBuffer; + const size_t IngestSize = CI_LAB_MAX_INGEST; + + IngestBuffer = CFE_SB_AllocateMessageBuffer(IngestSize); + if (IngestBuffer == NULL) + { + *BufferOut = NULL; + *SizeOut = 0; + + CFE_EVS_SendEvent(CI_LAB_INGEST_ALLOC_ERR_EID, CFE_EVS_EventType_ERROR, "CI_LAB: buffer allocation failed\n"); + + return CFE_SB_BUF_ALOC_ERR; + } + + *BufferOut = IngestBuffer; + *SizeOut = IngestSize; + + return CFE_SUCCESS; +} + +/* + * --------------------------------------- + * In a "passthrough" configuration - the data from the network + * is expected to be a direct instance of the CFE_MSG_Message_t base, + * and thus something can be sent directly to SB. + * + * This just does a simple sanity check on the message size. But + * otherwise, the source buffer is used directly as the output buffer. + * --------------------------------------- + */ +CFE_Status_t CI_LAB_DecodeInputMessage(void *SourceBuffer, size_t SourceSize, CFE_SB_Buffer_t **DestBufferOut) +{ + CFE_SB_Buffer_t *MsgBufPtr; + CFE_MSG_Size_t MsgSize; + CFE_Status_t Status; + + if (SourceSize < sizeof(CFE_MSG_CommandHeader_t)) + { + MsgBufPtr = NULL; + Status = CFE_STATUS_WRONG_MSG_LENGTH; + + CFE_EVS_SendEvent(CI_LAB_INGEST_LEN_ERR_EID, CFE_EVS_EventType_ERROR, + "CI: cmd dropped, bad packet length=%lu\n", (unsigned long)SourceSize); + } + else + { + MsgBufPtr = SourceBuffer; + + /* Check the size from within the header itself, compare against network buffer size */ + CFE_MSG_GetSize(&MsgBufPtr->Msg, &MsgSize); + + if (MsgSize > SourceSize) + { + Status = CFE_STATUS_WRONG_MSG_LENGTH; + + CFE_EVS_SendEvent(CI_LAB_INGEST_LEN_ERR_EID, CFE_EVS_EventType_ERROR, + "CI: cmd dropped - length mismatch, %lu (hdr) / %lu (packet)\n", (unsigned long)MsgSize, + (unsigned long)SourceSize); + } + else + { + Status = CFE_SUCCESS; + } + } + + *DestBufferOut = MsgBufPtr; + + return Status; +}