From 368cdc4d94332f724b21305c3d1aa20891c5a565 Mon Sep 17 00:00:00 2001 From: Avi Weiss Date: Mon, 19 Jun 2023 12:32:54 +1000 Subject: [PATCH 1/4] Fix #2386, Split up and simplify control flow in `CFE_TBL_Register()` --- modules/tbl/fsw/src/cfe_tbl_api.c | 451 +++++-------------------- modules/tbl/fsw/src/cfe_tbl_internal.c | 418 +++++++++++++++++++++++ modules/tbl/fsw/src/cfe_tbl_internal.h | 183 ++++++++++ 3 files changed, 681 insertions(+), 371 deletions(-) diff --git a/modules/tbl/fsw/src/cfe_tbl_api.c b/modules/tbl/fsw/src/cfe_tbl_api.c index 729bef4d2..b87155232 100644 --- a/modules/tbl/fsw/src/cfe_tbl_api.c +++ b/modules/tbl/fsw/src/cfe_tbl_api.c @@ -47,17 +47,13 @@ CFE_Status_t CFE_TBL_Register(CFE_TBL_Handle_t *TblHandlePtr, const char *Name, size_t Size, uint16 TblOptionFlags, CFE_TBL_CallbackFuncPtr_t TblValidationFuncPtr) { - CFE_TBL_AccessDescriptor_t *AccessDescPtr = NULL; - CFE_TBL_RegistryRec_t * RegRecPtr = NULL; - CFE_TBL_LoadBuff_t * WorkingBufferPtr; - CFE_TBL_CritRegRec_t * CritRegRecPtr = NULL; - int32 Status; - size_t NameLen; - int16 RegIndx; - CFE_ES_AppId_t ThisAppId; - char AppName[OS_MAX_API_NAME] = {"UNKNOWN"}; - char TblName[CFE_TBL_MAX_FULL_NAME_LEN] = {""}; - CFE_TBL_Handle_t AccessIndex; + CFE_TBL_RegistryRec_t *RegRecPtr = NULL; + CFE_TBL_CritRegRec_t * CritRegRecPtr = NULL; + CFE_Status_t Status; + int16 RegIndx; + CFE_ES_AppId_t ThisAppId; + char AppName[OS_MAX_API_NAME] = {"UNKNOWN"}; + char TblName[CFE_TBL_MAX_FULL_NAME_LEN] = {""}; if (TblHandlePtr == NULL || Name == NULL) { @@ -67,78 +63,24 @@ CFE_Status_t CFE_TBL_Register(CFE_TBL_Handle_t *TblHandlePtr, const char *Name, /* Check to make sure calling application is legit */ Status = CFE_ES_GetAppID(&ThisAppId); + /* Validate table input parameters (Name, Size and Options) */ if (Status == CFE_SUCCESS) { /* Assume we can't make a table and return a bad handle for now */ *TblHandlePtr = CFE_TBL_BAD_TABLE_HANDLE; - /* Make sure specified table name is not too long or too short */ - NameLen = strlen(Name); - if ((NameLen > CFE_MISSION_TBL_MAX_NAME_LENGTH) || (NameLen == 0)) - { - Status = CFE_TBL_ERR_INVALID_NAME; + Status = CFE_TBL_ValidateTableName(Name); - /* Perform a buffer overrun safe copy of name for debug log message */ - strncpy(TblName, Name, sizeof(TblName) - 1); - TblName[sizeof(TblName) - 1] = '\0'; - CFE_ES_WriteToSysLog("%s: Table Name (%s) is bad length (%d)", __func__, TblName, (int)NameLen); - } - else + if (Status == CFE_SUCCESS) { - /* Generate application specific table name */ + /* Generate the full application-specific table name if name validation was successful */ CFE_TBL_FormTableName(TblName, Name, ThisAppId); - /* Make sure the specified size is acceptable */ - /* Single buffered tables are allowed to be up to CFE_PLATFORM_TBL_MAX_SNGL_TABLE_SIZE */ - /* Double buffered tables are allowed to be up to CFE_PLATFORM_TBL_MAX_DBL_TABLE_SIZE */ - if (Size == 0) - { - Status = CFE_TBL_ERR_INVALID_SIZE; - - CFE_ES_WriteToSysLog("%s: Table %s has size of zero\n", __func__, Name); - } - else if ((Size > CFE_PLATFORM_TBL_MAX_SNGL_TABLE_SIZE) && - ((TblOptionFlags & CFE_TBL_OPT_BUFFER_MSK) == CFE_TBL_OPT_SNGL_BUFFER)) - { - Status = CFE_TBL_ERR_INVALID_SIZE; - - CFE_ES_WriteToSysLog("%s: Single Buffered Table '%s' has size %d > %d\n", __func__, Name, (int)Size, - CFE_PLATFORM_TBL_MAX_SNGL_TABLE_SIZE); - } - else if ((Size > CFE_PLATFORM_TBL_MAX_DBL_TABLE_SIZE) && - ((TblOptionFlags & CFE_TBL_OPT_BUFFER_MSK) == CFE_TBL_OPT_DBL_BUFFER)) - { - Status = CFE_TBL_ERR_INVALID_SIZE; - - CFE_ES_WriteToSysLog("%s: Dbl Buffered Table '%s' has size %d > %d\n", __func__, Name, (int)Size, - CFE_PLATFORM_TBL_MAX_DBL_TABLE_SIZE); - } + Status = CFE_TBL_ValidateTableSize(Name, Size, TblOptionFlags); - /* Verify Table Option settings are legal */ - /* User defined table addresses are only legal for single buffered, dump-only, non-critical tables */ - if ((TblOptionFlags & CFE_TBL_OPT_USR_DEF_MSK) == (CFE_TBL_OPT_USR_DEF_ADDR & CFE_TBL_OPT_USR_DEF_MSK)) - { - if (((TblOptionFlags & CFE_TBL_OPT_BUFFER_MSK) == CFE_TBL_OPT_DBL_BUFFER) || - ((TblOptionFlags & CFE_TBL_OPT_LD_DMP_MSK) == CFE_TBL_OPT_LOAD_DUMP) || - ((TblOptionFlags & CFE_TBL_OPT_CRITICAL_MSK) == CFE_TBL_OPT_CRITICAL)) - { - Status = CFE_TBL_ERR_INVALID_OPTIONS; - - CFE_ES_WriteToSysLog("%s: User Def tbl '%s' cannot be dbl buff, load/dump or critical\n", __func__, - Name); - } - } - else if ((TblOptionFlags & CFE_TBL_OPT_LD_DMP_MSK) == CFE_TBL_OPT_DUMP_ONLY) + if (Status == CFE_SUCCESS) { - /* Dump Only tables cannot be double buffered, nor critical */ - if (((TblOptionFlags & CFE_TBL_OPT_BUFFER_MSK) == CFE_TBL_OPT_DBL_BUFFER) || - ((TblOptionFlags & CFE_TBL_OPT_CRITICAL_MSK) == CFE_TBL_OPT_CRITICAL)) - { - Status = CFE_TBL_ERR_INVALID_OPTIONS; - - CFE_ES_WriteToSysLog("%s: Dump Only tbl '%s' cannot be double buffered or critical\n", __func__, - Name); - } + Status = CFE_TBL_ValidateTableOptions(Name, TblOptionFlags); } } } @@ -154,327 +96,96 @@ CFE_Status_t CFE_TBL_Register(CFE_TBL_Handle_t *TblHandlePtr, const char *Name, /* trying to register/share tables at the same location at the same time */ CFE_TBL_LockRegistry(); - /* Check for duplicate table name */ - RegIndx = CFE_TBL_FindTableInRegistry(TblName); + Status = CFE_TBL_CheckForDuplicateRegistration(&RegIndx, TblName, RegRecPtr, ThisAppId, Size, TblHandlePtr); - /* Check to see if table is already in the registry */ - if (RegIndx != CFE_TBL_NOT_FOUND) + /* In error conditions or if this is a duplicate registration, no further work is required */ + if (Status == CFE_SUCCESS) + { + /* Search Access Descriptor Array for free Descriptor */ + *TblHandlePtr = CFE_TBL_FindFreeHandle(); + + /* Check to make sure there was a handle available */ + if (*TblHandlePtr == CFE_TBL_END_OF_LIST) + { + Status = CFE_TBL_ERR_HANDLES_FULL; + CFE_ES_WriteToSysLog("%s: No more free handles\n", __func__); + } + } + + /* If no errors, initialize the table registry entry and return the index to the caller as the handle */ + if (Status == CFE_SUCCESS) { /* Get pointer to Registry Record Entry to speed up processing */ RegRecPtr = &CFE_TBL_Global.Registry[RegIndx]; - /* If this app previously owned the table, then allow them to re-register */ - if (CFE_RESOURCEID_TEST_EQUAL(RegRecPtr->OwnerAppId, ThisAppId)) + /* Initialize Registry Record to default settings */ + CFE_TBL_InitRegistryRecord(RegRecPtr); + + if ((TblOptionFlags & CFE_TBL_OPT_USR_DEF_MSK) != (CFE_TBL_OPT_USR_DEF_ADDR & CFE_TBL_OPT_USR_DEF_MSK)) { - /* If the new table is the same size as the old, then no need to reallocate memory */ - if (Size != RegRecPtr->Size) - { - /* If the new size is different, the old table must deleted */ - /* but this function can't do that because it is probably shared */ - /* and is probably still being accessed. Someone else will need */ - /* to clean up this mess. */ - Status = CFE_TBL_ERR_DUPLICATE_DIFF_SIZE; - - CFE_ES_WriteToSysLog("%s: Attempt to register existing table ('%s') with different size(%d!=%d)\n", - __func__, TblName, (int)Size, (int)RegRecPtr->Size); - } - else - { - /* Warn calling application that this is a duplicate registration */ - Status = CFE_TBL_WARN_DUPLICATE; - - /* Find the existing access descriptor for the table */ - /* and return the same handle that was returned previously */ - AccessIndex = RegRecPtr->HeadOfAccessList; - while ((AccessIndex != CFE_TBL_END_OF_LIST) && (*TblHandlePtr == CFE_TBL_BAD_TABLE_HANDLE)) - { - if ((CFE_TBL_Global.Handles[AccessIndex].UsedFlag == true) && - CFE_RESOURCEID_TEST_EQUAL(CFE_TBL_Global.Handles[AccessIndex].AppId, ThisAppId) && - (CFE_TBL_Global.Handles[AccessIndex].RegIndex == RegIndx)) - { - *TblHandlePtr = AccessIndex; - } - else - { - AccessIndex = CFE_TBL_Global.Handles[AccessIndex].NextLink; - } - } - } + RegRecPtr->UserDefAddr = false; + + Status = CFE_TBL_AllocateTableBuffer(RegRecPtr, Size); } - else /* Duplicate named table owned by another Application */ + else { - Status = CFE_TBL_ERR_DUPLICATE_NOT_OWNED; - - CFE_ES_WriteToSysLog("%s: App(%lu) Registering Duplicate Table '%s' owned by App(%lu)\n", __func__, - CFE_RESOURCEID_TO_ULONG(ThisAppId), TblName, - CFE_RESOURCEID_TO_ULONG(RegRecPtr->OwnerAppId)); + /* Set buffer pointer to NULL for user-defined address tables */ + RegRecPtr->Buffers[0].BufferPtr = NULL; + RegRecPtr->UserDefAddr = true; } - } - else /* Table not already in registry */ - { - /* Locate empty slot in table registry */ - RegIndx = CFE_TBL_FindFreeRegistryEntry(); - } - /* Check to make sure we found a free entry in registry */ - if (RegIndx == CFE_TBL_NOT_FOUND) - { - Status = CFE_TBL_ERR_REGISTRY_FULL; - CFE_ES_WriteToSysLog("%s: Registry full\n", __func__); + if (((TblOptionFlags & CFE_TBL_OPT_DBL_BUFFER) == CFE_TBL_OPT_DBL_BUFFER) && (Status == CFE_SUCCESS)) + { + Status = CFE_TBL_AllocateSecondaryBuffer(RegRecPtr, Size); + } + else /* Single-Buffered Table */ + { + RegRecPtr->DoubleBuffered = false; + RegRecPtr->ActiveBufferIndex = 0; + } } - /* If this is a duplicate registration, no other work is required */ - if (Status != CFE_TBL_WARN_DUPLICATE) + /* If memory allocation was successful, register with table services and the CDS (if applicable) */ + if (Status == CFE_SUCCESS) { - /* Search Access Descriptor Array for free Descriptor */ - *TblHandlePtr = CFE_TBL_FindFreeHandle(); + CFE_TBL_InitTableRegistryEntry(RegRecPtr, Size, TblValidationFuncPtr, TblName, TblOptionFlags); - /* Check to make sure there was a handle available */ - if (*TblHandlePtr == CFE_TBL_END_OF_LIST) - { - Status = CFE_TBL_ERR_HANDLES_FULL; - CFE_ES_WriteToSysLog("%s: No more free handles\n", __func__); - } + CFE_TBL_InitTableAccessDescriptor(TblHandlePtr, ThisAppId, RegRecPtr, RegIndx); - /* If no errors, then initialize the table registry entry */ - /* and return the registry index to the caller as the handle */ - if ((Status & CFE_SEVERITY_BITMASK) != CFE_SEVERITY_ERROR) + /* If the table is a critical table, allocate space for it in the Critical Data Store */ + /* OR locate its previous incarnation there and extract its previous contents */ + if ((TblOptionFlags & CFE_TBL_OPT_CRITICAL_MSK) == CFE_TBL_OPT_CRITICAL) { - /* Get pointer to Registry Record Entry to speed up processing */ - RegRecPtr = &CFE_TBL_Global.Registry[RegIndx]; + /* Register a CDS under the table name and determine if the table already exists there */ + Status = CFE_ES_RegisterCDSEx(&RegRecPtr->CDSHandle, Size, TblName, true); - /* Initialize Registry Record to default settings */ - CFE_TBL_InitRegistryRecord(RegRecPtr); + CFE_ES_GetAppName(AppName, ThisAppId, sizeof(AppName)); - if ((TblOptionFlags & CFE_TBL_OPT_USR_DEF_MSK) != (CFE_TBL_OPT_USR_DEF_ADDR & CFE_TBL_OPT_USR_DEF_MSK)) - { - RegRecPtr->UserDefAddr = false; - - /* Allocate the memory buffer(s) for the table and inactive table, if necessary */ - Status = CFE_ES_GetPoolBuf(&RegRecPtr->Buffers[0].BufferPtr, CFE_TBL_Global.Buf.PoolHdl, Size); - if (Status < 0) - { - CFE_ES_WriteToSysLog("%s: 1st Buf Alloc GetPool fail Stat=0x%08X MemPoolHndl=0x%08lX\n", - __func__, (unsigned int)Status, - CFE_RESOURCEID_TO_ULONG(CFE_TBL_Global.Buf.PoolHdl)); - } - else - { - /* Zero the memory buffer */ - Status = CFE_SUCCESS; - memset(RegRecPtr->Buffers[0].BufferPtr, 0x0, Size); - } - } - else + if (Status == CFE_ES_CDS_ALREADY_EXISTS) { - /* Set buffer pointer to NULL for user defined address tables */ - RegRecPtr->Buffers[0].BufferPtr = NULL; - RegRecPtr->UserDefAddr = true; + Status = CFE_TBL_RestoreTableDataFromCDS(RegRecPtr, AppName, Name, CritRegRecPtr); } - if (((TblOptionFlags & CFE_TBL_OPT_DBL_BUFFER) == CFE_TBL_OPT_DBL_BUFFER) && - ((Status & CFE_SEVERITY_BITMASK) != CFE_SEVERITY_ERROR)) + /* Don't need to register with Critical Table Registry if table data was recovered */ + if (Status == CFE_SUCCESS) { - /* Allocate memory for the dedicated secondary buffer */ - Status = CFE_ES_GetPoolBuf(&RegRecPtr->Buffers[1].BufferPtr, CFE_TBL_Global.Buf.PoolHdl, Size); - if (Status < 0) - { - CFE_ES_WriteToSysLog("%s: 2nd Buf Alloc GetPool fail Stat=0x%08X MemPoolHndl=0x%08lX\n", - __func__, (unsigned int)Status, - CFE_RESOURCEID_TO_ULONG(CFE_TBL_Global.Buf.PoolHdl)); - } - else - { - /* Zero the dedicated secondary buffer */ - Status = CFE_SUCCESS; - memset(RegRecPtr->Buffers[1].BufferPtr, 0x0, Size); - } - - RegRecPtr->ActiveBufferIndex = 0; - RegRecPtr->DoubleBuffered = true; + CFE_TBL_RegisterWithCriticalTableRegistry(CritRegRecPtr, RegRecPtr, TblName); } - else /* Single Buffered Table */ + else if (Status != CFE_TBL_INFO_RECOVERED_TBL) { - RegRecPtr->DoubleBuffered = false; - RegRecPtr->ActiveBufferIndex = 0; - } + CFE_ES_WriteToSysLog("%s: Failed to register '%s.%s' as a CDS (ErrCode=0x%08X)\n", __func__, + AppName, Name, (unsigned int)Status); - if ((Status & CFE_SEVERITY_BITMASK) != CFE_SEVERITY_ERROR) - { - /* Save the size of the table */ - RegRecPtr->Size = Size; - - /* Save the Callback function pointer */ - RegRecPtr->ValidationFuncPtr = TblValidationFuncPtr; - - /* Save Table Name in Registry */ - strncpy(RegRecPtr->Name, TblName, sizeof(RegRecPtr->Name) - 1); - RegRecPtr->Name[sizeof(RegRecPtr->Name) - 1] = '\0'; - - /* Set the "Dump Only" flag to value based upon selected option */ - if ((TblOptionFlags & CFE_TBL_OPT_LD_DMP_MSK) == CFE_TBL_OPT_DUMP_ONLY) - { - RegRecPtr->DumpOnly = true; - } - else - { - RegRecPtr->DumpOnly = false; - } - - /* Initialize the Table Access Descriptor */ - AccessDescPtr = &CFE_TBL_Global.Handles[*TblHandlePtr]; - - AccessDescPtr->AppId = ThisAppId; - AccessDescPtr->LockFlag = false; - AccessDescPtr->Updated = false; - - if ((RegRecPtr->DumpOnly) && (!RegRecPtr->UserDefAddr)) - { - /* Dump Only Tables are assumed to be loaded at all times */ - /* unless the address is specified by the application. In */ - /* that case, it isn't loaded until the address is specified */ - RegRecPtr->TableLoadedOnce = true; - } - - AccessDescPtr->RegIndex = RegIndx; - - AccessDescPtr->PrevLink = CFE_TBL_END_OF_LIST; /* We are the head of the list */ - AccessDescPtr->NextLink = CFE_TBL_END_OF_LIST; /* We are the end of the list */ - - AccessDescPtr->UsedFlag = true; - - /* Make sure the Table Registry entry points to First Access Descriptor */ - RegRecPtr->HeadOfAccessList = *TblHandlePtr; - - /* If the table is a critical table, allocate space for it in the Critical Data Store */ - /* OR locate its previous incarnation there and extract its previous contents */ - if ((TblOptionFlags & CFE_TBL_OPT_CRITICAL_MSK) == CFE_TBL_OPT_CRITICAL) - { - /* Register a CDS under the table name and determine if the table already exists there */ - Status = CFE_ES_RegisterCDSEx(&RegRecPtr->CDSHandle, Size, TblName, true); - - if (Status == CFE_ES_CDS_ALREADY_EXISTS) - { - Status = CFE_TBL_GetWorkingBuffer(&WorkingBufferPtr, RegRecPtr, true); - - if (Status != CFE_SUCCESS) - { - /* Unable to get a working buffer - this error is not really */ - /* possible at this point during table registration. But we */ - /* do need to handle the error case because if the function */ - /* call did fail, WorkingBufferPtr would be a NULL pointer. */ - CFE_ES_GetAppName(AppName, ThisAppId, sizeof(AppName)); - CFE_ES_WriteToSysLog("%s: Failed to get work buffer for '%s.%s' (ErrCode=0x%08X)\n", - __func__, AppName, Name, (unsigned int)Status); - } - else - { - /* CDS exists for this table - try to restore the data */ - Status = CFE_ES_RestoreFromCDS(WorkingBufferPtr->BufferPtr, RegRecPtr->CDSHandle); - - if (Status != CFE_SUCCESS) - { - CFE_ES_GetAppName(AppName, ThisAppId, sizeof(AppName)); - CFE_ES_WriteToSysLog("%s: Failed to recover '%s.%s' from CDS (ErrCode=0x%08X)\n", - __func__, AppName, Name, (unsigned int)Status); - } - } - - if (Status != CFE_SUCCESS) - { - /* Treat a restore from existing CDS error the same as */ - /* after a power-on reset (CDS was created but is empty) */ - Status = CFE_SUCCESS; - } - else - { - /* Try to locate the associated information in the Critical Table Registry */ - CFE_TBL_FindCriticalTblInfo(&CritRegRecPtr, RegRecPtr->CDSHandle); - - if ((CritRegRecPtr != NULL) && (CritRegRecPtr->TableLoadedOnce)) - { - strncpy(WorkingBufferPtr->DataSource, CritRegRecPtr->LastFileLoaded, - sizeof(WorkingBufferPtr->DataSource) - 1); - WorkingBufferPtr->DataSource[sizeof(WorkingBufferPtr->DataSource) - 1] = '\0'; - WorkingBufferPtr->FileCreateTimeSecs = CritRegRecPtr->FileCreateTimeSecs; - WorkingBufferPtr->FileCreateTimeSubSecs = CritRegRecPtr->FileCreateTimeSubSecs; - strncpy(RegRecPtr->LastFileLoaded, CritRegRecPtr->LastFileLoaded, - sizeof(RegRecPtr->LastFileLoaded) - 1); - RegRecPtr->LastFileLoaded[sizeof(RegRecPtr->LastFileLoaded) - 1] = '\0'; - RegRecPtr->TimeOfLastUpdate.Seconds = CritRegRecPtr->TimeOfLastUpdate.Seconds; - RegRecPtr->TimeOfLastUpdate.Subseconds = CritRegRecPtr->TimeOfLastUpdate.Subseconds; - RegRecPtr->TableLoadedOnce = CritRegRecPtr->TableLoadedOnce; - - /* Compute the CRC on the specified table buffer */ - WorkingBufferPtr->Crc = CFE_ES_CalculateCRC( - WorkingBufferPtr->BufferPtr, RegRecPtr->Size, 0, CFE_MISSION_ES_DEFAULT_CRC); - - /* Make sure everyone who sees the table knows that it has been updated */ - CFE_TBL_NotifyTblUsersOfUpdate(RegRecPtr); - - /* Make sure the caller realizes the contents have been initialized */ - Status = CFE_TBL_INFO_RECOVERED_TBL; - } - else - { - /* If an error occurred while trying to get the previous contents registry info, */ - /* Log the error in the System Log and pretend like we created a new CDS */ - CFE_ES_GetAppName(AppName, ThisAppId, sizeof(AppName)); - CFE_ES_WriteToSysLog("%s: Failed to recover '%s.%s' info from CDS TblReg\n", - __func__, AppName, Name); - Status = CFE_SUCCESS; - } - } - - /* Mark the table as critical for future reference */ - RegRecPtr->CriticalTable = true; - } - - if (Status == CFE_SUCCESS) - { - /* Find and initialize a free entry in the Critical Table Registry */ - CFE_TBL_FindCriticalTblInfo(&CritRegRecPtr, CFE_ES_CDS_BAD_HANDLE); - - if (CritRegRecPtr != NULL) - { - CritRegRecPtr->CDSHandle = RegRecPtr->CDSHandle; - strncpy(CritRegRecPtr->Name, TblName, sizeof(CritRegRecPtr->Name) - 1); - CritRegRecPtr->Name[sizeof(CritRegRecPtr->Name) - 1] = '\0'; - CritRegRecPtr->FileCreateTimeSecs = 0; - CritRegRecPtr->FileCreateTimeSubSecs = 0; - CritRegRecPtr->LastFileLoaded[0] = '\0'; - CritRegRecPtr->TimeOfLastUpdate.Seconds = 0; - CritRegRecPtr->TimeOfLastUpdate.Subseconds = 0; - CritRegRecPtr->TableLoadedOnce = false; - - CFE_ES_CopyToCDS(CFE_TBL_Global.CritRegHandle, CFE_TBL_Global.CritReg); - } - else - { - CFE_ES_WriteToSysLog("%s: Failed to find a free Crit Tbl Reg Rec for '%s'\n", __func__, - RegRecPtr->Name); - } - - /* Mark the table as critical for future reference */ - RegRecPtr->CriticalTable = true; - } - else if (Status != CFE_TBL_INFO_RECOVERED_TBL) - { - CFE_ES_WriteToSysLog("%s: Failed to register '%s.%s' as a CDS (ErrCode=0x%08X)\n", __func__, - AppName, Name, (unsigned int)Status); - - /* Notify caller that although they asked for it to be critical, it isn't */ - Status = CFE_TBL_WARN_NOT_CRITICAL; - } - } - - /* The last step of the registration process is claiming ownership. */ - /* By making it the last step, other APIs do not have to lock registry */ - /* to share the table or get its address because registry entries that */ - /* are unowned are not checked to see if they match names, etc. */ - RegRecPtr->OwnerAppId = ThisAppId; + /* Notify caller that although they asked for it to be critical, it isn't */ + Status = CFE_TBL_WARN_NOT_CRITICAL; } } + + /* The last step of the registration process is claiming ownership. */ + /* By making it the last step, other APIs do not have to lock registry */ + /* to share the table or get its address because registry entries that */ + /* are unowned are not checked to see if they match names, etc. */ + RegRecPtr->OwnerAppId = ThisAppId; } /* Unlock Registry for update */ @@ -487,9 +198,7 @@ CFE_Status_t CFE_TBL_Register(CFE_TBL_Handle_t *TblHandlePtr, const char *Name, /* Make sure the returned handle is invalid when an error occurs */ *TblHandlePtr = CFE_TBL_BAD_TABLE_HANDLE; - /* Translate AppID of caller into App Name */ - CFE_ES_GetAppName(AppName, ThisAppId, sizeof(AppName)); - + CFE_ES_GetAppName(AppName, ThisAppId, sizeof(AppName)); /* Get app name in case not avilable from earlier */ CFE_EVS_SendEventWithAppID(CFE_TBL_REGISTER_ERR_EID, CFE_EVS_EventType_ERROR, CFE_TBL_Global.TableTaskAppId, "%s Failed to Register '%s', Status=0x%08X", AppName, TblName, (unsigned int)Status); } @@ -829,11 +538,11 @@ CFE_Status_t CFE_TBL_Load(CFE_TBL_Handle_t TblHandle, CFE_TBL_SrcEnum_t SrcType, /* The load has had a problem, free the working buffer for another attempt */ if ((!RegRecPtr->DoubleBuffered) && (RegRecPtr->TableLoadedOnce == true)) { - /* For single buffered tables, freeing entails resetting flag */ + /* For single-buffered tables, freeing entails resetting flag */ CFE_TBL_Global.LoadBuffs[RegRecPtr->LoadInProgress].Taken = false; } - /* For double buffered tables, freeing buffer is simple */ + /* For double-buffered tables, freeing buffer is simple */ RegRecPtr->LoadInProgress = CFE_TBL_NO_LOAD_IN_PROGRESS; return Status; diff --git a/modules/tbl/fsw/src/cfe_tbl_internal.c b/modules/tbl/fsw/src/cfe_tbl_internal.c index b127c0189..4672cbc10 100644 --- a/modules/tbl/fsw/src/cfe_tbl_internal.c +++ b/modules/tbl/fsw/src/cfe_tbl_internal.c @@ -1390,3 +1390,421 @@ int32 CFE_TBL_SendNotificationMsg(CFE_TBL_RegistryRec_t *RegRecPtr) return Status; } + +/*---------------------------------------------------------------- + * + * Application-scope internal function + * See description in header file for argument/return detail + * + *-----------------------------------------------------------------*/ +CFE_Status_t CFE_TBL_ValidateTableName(const char *Name) +{ + CFE_Status_t Status = CFE_SUCCESS; + size_t NameLength = strlen(Name); + char TempTblName[CFE_TBL_MAX_FULL_NAME_LEN]; + + /* Make sure the specified table name is not too long or too short */ + if (NameLength > CFE_MISSION_TBL_MAX_NAME_LENGTH || NameLength == 0) + { + Status = CFE_TBL_ERR_INVALID_NAME; + + /* Perform a buffer overrun safe copy of name for debug log message */ + strncpy(TempTblName, Name, sizeof(TempTblName) - 1); + TempTblName[sizeof(TempTblName) - 1] = '\0'; + CFE_ES_WriteToSysLog("%s: Table Name (%s) is bad length (%d)", __func__, TempTblName, (int)NameLength); + } + + return Status; +} + +/*---------------------------------------------------------------- + * + * Application-scope internal function + * See description in header file for argument/return detail + * + *-----------------------------------------------------------------*/ +CFE_Status_t CFE_TBL_ValidateTableSize(const char *Name, size_t Size, uint16 TblOptionFlags) +{ + CFE_Status_t Status = CFE_SUCCESS; + + /* Check if the specified table size is zero, or above the maximum allowed */ + /* Single-buffered tables are allowed to be up to CFE_PLATFORM_TBL_MAX_SNGL_TABLE_SIZE */ + /* Double-buffered tables are allowed to be up to CFE_PLATFORM_TBL_MAX_DBL_TABLE_SIZE */ + if (Size == 0 || + (Size > CFE_PLATFORM_TBL_MAX_SNGL_TABLE_SIZE && + (TblOptionFlags & CFE_TBL_OPT_BUFFER_MSK) == CFE_TBL_OPT_SNGL_BUFFER) || + (Size > CFE_PLATFORM_TBL_MAX_DBL_TABLE_SIZE && + (TblOptionFlags & CFE_TBL_OPT_BUFFER_MSK) == CFE_TBL_OPT_DBL_BUFFER)) + { + Status = CFE_TBL_ERR_INVALID_SIZE; + + CFE_ES_WriteToSysLog("%s: Table '%s' has invalid size (%d)\n", __func__, Name, (int)Size); + } + + return Status; +} + +/*---------------------------------------------------------------- + * + * Application-scope internal function + * See description in header file for argument/return detail + * + *-----------------------------------------------------------------*/ +CFE_Status_t CFE_TBL_ValidateTableOptions(const char *Name, uint16 TblOptionFlags) +{ + CFE_Status_t Status = CFE_SUCCESS; + + /* User-defined table addresses are only legal for single-buffered, dump-only, non-critical tables */ + if ((TblOptionFlags & CFE_TBL_OPT_USR_DEF_MSK) == (CFE_TBL_OPT_USR_DEF_ADDR & CFE_TBL_OPT_USR_DEF_MSK)) + { + if (((TblOptionFlags & CFE_TBL_OPT_BUFFER_MSK) == CFE_TBL_OPT_DBL_BUFFER) || + ((TblOptionFlags & CFE_TBL_OPT_LD_DMP_MSK) == CFE_TBL_OPT_LOAD_DUMP) || + ((TblOptionFlags & CFE_TBL_OPT_CRITICAL_MSK) == CFE_TBL_OPT_CRITICAL)) + { + Status = CFE_TBL_ERR_INVALID_OPTIONS; + + CFE_ES_WriteToSysLog("%s: User Def tbl '%s' cannot be dbl buff, load/dump or critical\n", __func__, Name); + } + } + else if ((TblOptionFlags & CFE_TBL_OPT_LD_DMP_MSK) == CFE_TBL_OPT_DUMP_ONLY) + { + /* Dump Only tables cannot be double-buffered, nor critical */ + if (((TblOptionFlags & CFE_TBL_OPT_BUFFER_MSK) == CFE_TBL_OPT_DBL_BUFFER) || + ((TblOptionFlags & CFE_TBL_OPT_CRITICAL_MSK) == CFE_TBL_OPT_CRITICAL)) + { + Status = CFE_TBL_ERR_INVALID_OPTIONS; + + CFE_ES_WriteToSysLog("%s: Dump Only tbl '%s' cannot be double-buffered or critical\n", __func__, Name); + } + } + + return Status; +} + +/*---------------------------------------------------------------- + * + * Application-scope internal function + * See description in header file for argument/return detail + * + *-----------------------------------------------------------------*/ +CFE_Status_t CFE_TBL_CheckForDuplicateRegistration(int16 *RegIndxPtr, const char *TblName, + CFE_TBL_RegistryRec_t *RegRecPtr, CFE_ES_AppId_t ThisAppId, + size_t Size, CFE_TBL_Handle_t *TblHandlePtr) +{ + CFE_Status_t Status = CFE_SUCCESS; + CFE_TBL_Handle_t AccessIndex; + + /* Check for duplicate table name */ + *RegIndxPtr = CFE_TBL_FindTableInRegistry(TblName); + + /* Check to see if table is already in the registry */ + if (*RegIndxPtr != CFE_TBL_NOT_FOUND) + { + /* Get pointer to Registry Record Entry to speed up processing */ + RegRecPtr = &CFE_TBL_Global.Registry[*RegIndxPtr]; + + /* If this app previously owned the table, then allow them to re-register */ + if (CFE_RESOURCEID_TEST_EQUAL(RegRecPtr->OwnerAppId, ThisAppId)) + { + /* If the new table is the same size as the old, then no need to reallocate memory */ + if (Size != RegRecPtr->Size) + { + /* If the new size is different, the old table must be deleted but this */ + /* function can't do that because it is probably shared and is probably */ + /* still being accessed. Someone else will need to clean up this mess. */ + Status = CFE_TBL_ERR_DUPLICATE_DIFF_SIZE; + + CFE_ES_WriteToSysLog("%s: Attempt to register existing table ('%s') with different size(%d!=%d)\n", + __func__, TblName, (int)Size, (int)RegRecPtr->Size); + } + else + { + /* Warn calling application that this is a duplicate registration */ + Status = CFE_TBL_WARN_DUPLICATE; + + /* Find the existing access descriptor for the table */ + /* and return the same handle that was returned previously */ + AccessIndex = RegRecPtr->HeadOfAccessList; + while ((AccessIndex != CFE_TBL_END_OF_LIST) && (*TblHandlePtr == CFE_TBL_BAD_TABLE_HANDLE)) + { + if ((CFE_TBL_Global.Handles[AccessIndex].UsedFlag == true) && + CFE_RESOURCEID_TEST_EQUAL(CFE_TBL_Global.Handles[AccessIndex].AppId, ThisAppId) && + (CFE_TBL_Global.Handles[AccessIndex].RegIndex == *RegIndxPtr)) + { + *TblHandlePtr = AccessIndex; + } + else + { + AccessIndex = CFE_TBL_Global.Handles[AccessIndex].NextLink; + } + } + } + } + else /* Duplicate named table owned by another Application */ + { + Status = CFE_TBL_ERR_DUPLICATE_NOT_OWNED; + + CFE_ES_WriteToSysLog("%s: App(%lu) Registering Duplicate Table '%s' owned by App(%lu)\n", __func__, + CFE_RESOURCEID_TO_ULONG(ThisAppId), TblName, + CFE_RESOURCEID_TO_ULONG(RegRecPtr->OwnerAppId)); + } + } + else /* Table not already in registry */ + { + /* Locate empty slot in table registry */ + *RegIndxPtr = CFE_TBL_FindFreeRegistryEntry(); + + /* Check if the registry was full and set error status if it was */ + if (*RegIndxPtr == CFE_TBL_NOT_FOUND) + { + Status = CFE_TBL_ERR_REGISTRY_FULL; + CFE_ES_WriteToSysLog("CFE_TBL:Register-Registry full\n"); + } + } + + return Status; +} + +/*---------------------------------------------------------------- + * + * Application-scope internal function + * See description in header file for argument/return detail + * + *-----------------------------------------------------------------*/ +CFE_Status_t CFE_TBL_AllocateTableBuffer(CFE_TBL_RegistryRec_t *RegRecPtr, size_t Size) +{ + CFE_Status_t Status; + + /* Allocate the memory buffer(s) for the table and inactive table, if necessary */ + Status = CFE_ES_GetPoolBuf(&RegRecPtr->Buffers[0].BufferPtr, CFE_TBL_Global.Buf.PoolHdl, Size); + + if (Status < 0) + { + CFE_ES_WriteToSysLog("%s: 1st Buf Alloc GetPool fail Stat=0x%08X MemPoolHndl=0x%08lX\n", __func__, + (unsigned int)Status, CFE_RESOURCEID_TO_ULONG(CFE_TBL_Global.Buf.PoolHdl)); + } + else + { + Status = CFE_SUCCESS; + + /* Zero the memory buffer */ + memset(RegRecPtr->Buffers[0].BufferPtr, 0x0, Size); + } + + return Status; +} + +/*---------------------------------------------------------------- + * + * Application-scope internal function + * See description in header file for argument/return detail + * + *-----------------------------------------------------------------*/ +CFE_Status_t CFE_TBL_AllocateSecondaryBuffer(CFE_TBL_RegistryRec_t *RegRecPtr, size_t Size) +{ + CFE_Status_t Status; + + /* Allocate memory for the dedicated secondary buffer */ + Status = CFE_ES_GetPoolBuf(&RegRecPtr->Buffers[1].BufferPtr, CFE_TBL_Global.Buf.PoolHdl, Size); + + if (Status < 0) + { + CFE_ES_WriteToSysLog("%s: 2nd Buf Alloc GetPool fail Stat=0x%08X MemPoolHndl=0x%08lX\n", __func__, + (unsigned int)Status, CFE_RESOURCEID_TO_ULONG(CFE_TBL_Global.Buf.PoolHdl)); + } + else + { + Status = CFE_SUCCESS; + + /* Zero the dedicated secondary buffer */ + memset(RegRecPtr->Buffers[1].BufferPtr, 0x0, Size); + } + + RegRecPtr->ActiveBufferIndex = 0; + RegRecPtr->DoubleBuffered = true; + + return Status; +} + +/*---------------------------------------------------------------- + * + * Application-scope internal function + * See description in header file for argument/return detail + * + *-----------------------------------------------------------------*/ +void CFE_TBL_InitTableRegistryEntry(CFE_TBL_RegistryRec_t *RegRecPtr, size_t Size, + CFE_TBL_CallbackFuncPtr_t TblValidationFuncPtr, const char *TblName, + uint16 TblOptionFlags) +{ + /* Save the size of the table */ + RegRecPtr->Size = Size; + + /* Save the Callback function pointer */ + RegRecPtr->ValidationFuncPtr = TblValidationFuncPtr; + + /* Save Table Name in Registry */ + strncpy(RegRecPtr->Name, TblName, sizeof(RegRecPtr->Name) - 1); + RegRecPtr->Name[sizeof(RegRecPtr->Name) - 1] = '\0'; + + /* Set the "Dump Only" flag to true/false based upon selected option */ + RegRecPtr->DumpOnly = ((TblOptionFlags & CFE_TBL_OPT_LD_DMP_MSK) == CFE_TBL_OPT_DUMP_ONLY); +} + +/*---------------------------------------------------------------- + * + * Application-scope internal function + * See description in header file for argument/return detail + * + *-----------------------------------------------------------------*/ +void CFE_TBL_InitTableAccessDescriptor(CFE_TBL_Handle_t *TblHandlePtr, CFE_ES_AppId_t ThisAppId, + CFE_TBL_RegistryRec_t *RegRecPtr, int16 RegIndx) +{ + CFE_TBL_AccessDescriptor_t *AccessDescPtr = NULL; + + /* Initialize the Table Access Descriptor */ + AccessDescPtr = &CFE_TBL_Global.Handles[*TblHandlePtr]; + + AccessDescPtr->AppId = ThisAppId; + AccessDescPtr->LockFlag = false; + AccessDescPtr->Updated = false; + + if ((RegRecPtr->DumpOnly) && (!RegRecPtr->UserDefAddr)) + { + /* Dump Only Tables are assumed to be loaded at all times unless the address is specified */ + /* by the application. In that case, it isn't loaded until the address is specified */ + RegRecPtr->TableLoadedOnce = true; + } + + AccessDescPtr->RegIndex = RegIndx; + + AccessDescPtr->PrevLink = CFE_TBL_END_OF_LIST; /* We are the head of the list */ + AccessDescPtr->NextLink = CFE_TBL_END_OF_LIST; /* We are the end of the list */ + + AccessDescPtr->UsedFlag = true; + + /* Make sure the Table Registry entry points to First Access Descriptor */ + RegRecPtr->HeadOfAccessList = *TblHandlePtr; +} + +/*---------------------------------------------------------------- + * + * Application-scope internal function + * See description in header file for argument/return detail + * + *-----------------------------------------------------------------*/ + +CFE_Status_t CFE_TBL_RestoreTableDataFromCDS(CFE_TBL_RegistryRec_t *RegRecPtr, const char *AppName, const char *Name, + CFE_TBL_CritRegRec_t *CritRegRecPtr) +{ + CFE_Status_t Status = CFE_SUCCESS; + CFE_TBL_LoadBuff_t *WorkingBufferPtr; + + Status = CFE_TBL_GetWorkingBuffer(&WorkingBufferPtr, RegRecPtr, true); + + if (Status != CFE_SUCCESS) + { + /* Unable to get a working buffer - this error is not really */ + /* possible at this point during table registration. But we */ + /* do need to handle the error case because if the function */ + /* call did fail, WorkingBufferPtr would be a NULL pointer. */ + CFE_ES_WriteToSysLog("%s: Failed to get work buffer for '%s.%s' (ErrCode=0x%08X)\n", __func__, AppName, Name, + (unsigned int)Status); + } + else + { + /* CDS exists for this table - try to restore the data */ + Status = CFE_ES_RestoreFromCDS(WorkingBufferPtr->BufferPtr, RegRecPtr->CDSHandle); + + if (Status != CFE_SUCCESS) + { + CFE_ES_WriteToSysLog("%s: Failed to recover '%s.%s' from CDS (ErrCode=0x%08X)\n", __func__, AppName, Name, + (unsigned int)Status); + } + } + + if (Status != CFE_SUCCESS) + { + /* Treat a restore from existing CDS error the same as */ + /* after a power-on reset (CDS was created but is empty) */ + Status = CFE_SUCCESS; + } + else + { + /* Try to locate the associated information in the Critical Table Registry */ + CFE_TBL_FindCriticalTblInfo(&CritRegRecPtr, RegRecPtr->CDSHandle); + + if ((CritRegRecPtr != NULL) && (CritRegRecPtr->TableLoadedOnce)) + { + strncpy(WorkingBufferPtr->DataSource, CritRegRecPtr->LastFileLoaded, + sizeof(WorkingBufferPtr->DataSource) - 1); + WorkingBufferPtr->DataSource[sizeof(WorkingBufferPtr->DataSource) - 1] = '\0'; + + WorkingBufferPtr->FileCreateTimeSecs = CritRegRecPtr->FileCreateTimeSecs; + WorkingBufferPtr->FileCreateTimeSubSecs = CritRegRecPtr->FileCreateTimeSubSecs; + + strncpy(RegRecPtr->LastFileLoaded, CritRegRecPtr->LastFileLoaded, sizeof(RegRecPtr->LastFileLoaded) - 1); + RegRecPtr->LastFileLoaded[sizeof(RegRecPtr->LastFileLoaded) - 1] = '\0'; + + RegRecPtr->TimeOfLastUpdate.Seconds = CritRegRecPtr->TimeOfLastUpdate.Seconds; + RegRecPtr->TimeOfLastUpdate.Subseconds = CritRegRecPtr->TimeOfLastUpdate.Subseconds; + RegRecPtr->TableLoadedOnce = CritRegRecPtr->TableLoadedOnce; + + /* Compute the CRC on the specified table buffer */ + WorkingBufferPtr->Crc = + CFE_ES_CalculateCRC(WorkingBufferPtr->BufferPtr, RegRecPtr->Size, 0, CFE_MISSION_ES_DEFAULT_CRC); + + /* Make sure everyone who sees the table knows that it has been updated */ + CFE_TBL_NotifyTblUsersOfUpdate(RegRecPtr); + + /* Make sure the caller realizes the contents have been initialized */ + Status = CFE_TBL_INFO_RECOVERED_TBL; + } + else + { + /* If an error occurred while trying to get the previous contents registry info, */ + /* Log the error in the System Log and pretend like we created a new CDS */ + CFE_ES_WriteToSysLog("%s: Failed to recover '%s.%s' info from CDS TblReg\n", __func__, AppName, Name); + Status = CFE_SUCCESS; + } + } + + /* Mark the table as critical for future reference */ + RegRecPtr->CriticalTable = true; + + return Status; +} + +/*---------------------------------------------------------------- + * + * Application-scope internal function + * See description in header file for argument/return detail + * + *-----------------------------------------------------------------*/ +void CFE_TBL_RegisterWithCriticalTableRegistry(CFE_TBL_CritRegRec_t *CritRegRecPtr, CFE_TBL_RegistryRec_t *RegRecPtr, + const char *TblName) +{ + /* Find and initialize a free entry in the Critical Table Registry */ + CFE_TBL_FindCriticalTblInfo(&CritRegRecPtr, CFE_ES_CDS_BAD_HANDLE); + + if (CritRegRecPtr != NULL) + { + CritRegRecPtr->CDSHandle = RegRecPtr->CDSHandle; + strncpy(CritRegRecPtr->Name, TblName, sizeof(CritRegRecPtr->Name) - 1); + CritRegRecPtr->Name[sizeof(CritRegRecPtr->Name) - 1] = '\0'; + CritRegRecPtr->FileCreateTimeSecs = 0; + CritRegRecPtr->FileCreateTimeSubSecs = 0; + CritRegRecPtr->LastFileLoaded[0] = '\0'; + CritRegRecPtr->TimeOfLastUpdate.Seconds = 0; + CritRegRecPtr->TimeOfLastUpdate.Subseconds = 0; + CritRegRecPtr->TableLoadedOnce = false; + + CFE_ES_CopyToCDS(CFE_TBL_Global.CritRegHandle, CFE_TBL_Global.CritReg); + } + else + { + CFE_ES_WriteToSysLog("%s: Failed to find a free Crit Tbl Reg Rec for '%s'\n", __func__, RegRecPtr->Name); + } + + /* Mark the table as critical for future reference */ + RegRecPtr->CriticalTable = true; +} \ No newline at end of file diff --git a/modules/tbl/fsw/src/cfe_tbl_internal.h b/modules/tbl/fsw/src/cfe_tbl_internal.h index 556394ffa..8f96b12e1 100644 --- a/modules/tbl/fsw/src/cfe_tbl_internal.h +++ b/modules/tbl/fsw/src/cfe_tbl_internal.h @@ -560,6 +560,189 @@ void CFE_TBL_DumpRegistryEventHandler(void *Meta, CFE_FS_FileWriteEvent_t Event, size_t BlockSize, size_t Position); bool CFE_TBL_DumpRegistryGetter(void *Meta, uint32 RecordNum, void **Buffer, size_t *BufSize); +/* + * Internal helper functions for CFE_TBL_Register() + * + * These functions execute the table registration process but are + * separated out into the most cohesive logical blocks of work. + * + */ + +/*---------------------------------------------------------------------------------------*/ +/** +** \brief Validates the table name of a table to be registered +** +** \par Description +** Validates the length of a table name for a table that is being registered. It +** checks that the length of the name is not zero, nor too long (longer than +** CFE_MISSION_TBL_MAX_NAME_LENGTH). +** +** \par Assumptions, External Events, and Notes: +** None +** +** \retval #CFE_SUCCESS \copydoc CFE_SUCCESS +** \retval #CFE_TBL_ERR_INVALID_NAME \copydoc CFE_TBL_ERR_INVALID_NAME +** +*/ +CFE_Status_t CFE_TBL_ValidateTableName(const char *Name); + +/*---------------------------------------------------------------------------------------*/ +/** +** \brief Validates the size of the table to be registered +** +** \par Description +** This function validates the size of the table that is being registered. It +** checks that the size is not zero, and that single/double-buffered tables are +** not requested to be of a size larger than their respective limits +** (CFE_PLATFORM_TBL_MAX_SNGL_TABLE_SIZE & CFE_PLATFORM_TBL_MAX_DBL_TABLE_SIZE). +** +** \par Assumptions, External Events, and Notes: +** None +** +** \retval #CFE_SUCCESS \copydoc CFE_SUCCESS +** \retval #CFE_TBL_ERR_INVALID_SIZE \copydoc CFE_TBL_ERR_INVALID_SIZE +** +*/ +CFE_Status_t CFE_TBL_ValidateTableSize(const char *Name, size_t Size, uint16 TblOptionFlags); + +/*---------------------------------------------------------------------------------------*/ +/** +** \brief Validates the selected table options +** +** \par Description +** Validates the selected table options for a table that is being registered. +** User-defined table addresses cannot be double-buffered, load/dump or critical. +** Dump-only tables cannot be double-buffered or critical. +** +** \par Assumptions, External Events, and Notes: +** None +** +** \retval #CFE_SUCCESS \copydoc CFE_SUCCESS +** \retval #CFE_TBL_ERR_INVALID_OPTIONS \copydoc CFE_TBL_ERR_INVALID_OPTIONS +** +*/ +CFE_Status_t CFE_TBL_ValidateTableOptions(const char *Name, uint16 TblOptionFlags); + +/*---------------------------------------------------------------------------------------*/ +/** +** \brief Checks if a table is already registered in the Table Registry +** +** \par Description +** This routine searches the Table Registry for a table with the specified name, +** owning app and size. If a match is found, the same handle is returned. If a +** match is not found, the function will locate a free slot in the table registry +** (unless it's already full). +** +** \par Assumptions, External Events, and Notes: +** None +** +** \retval #CFE_SUCCESS \copydoc CFE_SUCCESS +** \retval #CFE_TBL_ERR_DUPLICATE_DIFF_SIZE \copydoc CFE_TBL_ERR_DUPLICATE_DIFF_SIZE +** \retval #CFE_TBL_WARN_DUPLICATE \copydoc CFE_TBL_WARN_DUPLICATE +** \retval #CFE_TBL_ERR_DUPLICATE_NOT_OWNED \copydoc CFE_TBL_ERR_DUPLICATE_NOT_OWNED +** \retval #CFE_TBL_ERR_REGISTRY_FULL \copydoc CFE_TBL_ERR_REGISTRY_FULL +** +*/ +CFE_Status_t CFE_TBL_CheckForDuplicateRegistration(int16 *RegIndxPtr, const char *TblName, + CFE_TBL_RegistryRec_t *RegRecPtr, CFE_ES_AppId_t ThisAppId, + size_t Size, CFE_TBL_Handle_t *TblHandlePtr); + +/*---------------------------------------------------------------------------------------*/ +/** +** \brief Allocates memory for the table buffer +** +** \par Description +** Allocates a memory buffer for the table buffer of a table that is being registered. +** If successful, the buffer is zeroed out. +** +** \par Assumptions, External Events, and Notes: +** None +** +** \retval #CFE_SUCCESS \copydoc CFE_SUCCESS +** +*/ +CFE_Status_t CFE_TBL_AllocateTableBuffer(CFE_TBL_RegistryRec_t *RegRecPtr, size_t Size); + +/*---------------------------------------------------------------------------------------*/ +/** +** \brief Allocates the secondary memory buffer for a double-buffered table +** +** \par Description +** Allocates the secondary memory buffer for a double-buffered table that is +** being registered. If successful, the buffer is zeroed out, and the +** DoubleBuffered flag is set to true. +** +** \par Assumptions, External Events, and Notes: +** None +** +** \retval #CFE_SUCCESS \copydoc CFE_SUCCESS +** +*/ +CFE_Status_t CFE_TBL_AllocateSecondaryBuffer(CFE_TBL_RegistryRec_t *RegRecPtr, size_t Size); + +/*---------------------------------------------------------------------------------------*/ +/** +** \brief Initializes a Table Registry Entry +** +** \par Description +** Initializes a Table Registry Entry for a table that is being registered +** +** \par Assumptions, External Events, and Notes: +** None +** +*/ +void CFE_TBL_InitTableRegistryEntry(CFE_TBL_RegistryRec_t *RegRecPtr, size_t Size, + CFE_TBL_CallbackFuncPtr_t TblValidationFuncPtr, const char *TblName, + uint16 TblOptionFlags); + +/*---------------------------------------------------------------------------------------*/ +/** +** \brief Initializes a Table Access Descriptor +** +** \par Description +** Initializes a Table Access Descriptor for a table that is being registered +** +** \par Assumptions, External Events, and Notes: +** None +** +*/ +void CFE_TBL_InitTableAccessDescriptor(CFE_TBL_Handle_t *TblHandlePtr, CFE_ES_AppId_t ThisAppId, + CFE_TBL_RegistryRec_t *RegRecPtr, int16 RegIndx); + +/*---------------------------------------------------------------------------------------*/ +/** +** \brief Restore the contents of a table from the Critical Data Store (if it exists) +** +** \par Description +** This function restores the contents of the specified table from the Critical +** Data Store (CDS), if a copy of the table contents exists there. +** +** \par Assumptions, External Events, and Notes: +** None +** +** \retval #CFE_SUCCESS \copydoc CFE_SUCCESS +** \retval #CFE_TBL_INFO_RECOVERED_TBL \copydoc CFE_TBL_INFO_RECOVERED_TBL +** +*/ +CFE_Status_t CFE_TBL_RestoreTableDataFromCDS(CFE_TBL_RegistryRec_t *RegRecPtr, const char *AppName, const char *Name, + CFE_TBL_CritRegRec_t *CritRegRecPtr); + +/*---------------------------------------------------------------------------------------*/ +/** +** \brief Register a table with the Critical Table Registry +** +** \par Description +** This function registers a table with the Critical Table Registry. The fields of +** the Critical Table Registry Record are initialized and then the data is copied +** to the Critical Data Store (CDS). +** +** \par Assumptions, External Events, and Notes: +** None +** +*/ +void CFE_TBL_RegisterWithCriticalTableRegistry(CFE_TBL_CritRegRec_t *CritRegRecPtr, CFE_TBL_RegistryRec_t *RegRecPtr, + const char *TblName); + /* ** Globals specific to the TBL module */ From 8962f4749cdaed340dab9cbc77998625a953cf11 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Thu, 14 Mar 2024 09:57:45 -0400 Subject: [PATCH 2/4] Fix #2387, update for unit test coverage Corrects some missed branches and lines in the unit test --- modules/tbl/fsw/src/cfe_tbl_api.c | 18 ++--- modules/tbl/fsw/src/cfe_tbl_internal.c | 101 ++++++++++++++----------- modules/tbl/ut-coverage/tbl_UT.c | 41 ++++++++-- 3 files changed, 99 insertions(+), 61 deletions(-) diff --git a/modules/tbl/fsw/src/cfe_tbl_api.c b/modules/tbl/fsw/src/cfe_tbl_api.c index b87155232..5333557b7 100644 --- a/modules/tbl/fsw/src/cfe_tbl_api.c +++ b/modules/tbl/fsw/src/cfe_tbl_api.c @@ -645,17 +645,13 @@ CFE_Status_t CFE_TBL_Update(CFE_TBL_Handle_t TblHandle) /* On Error conditions, notify ground of screw up */ if (Status < 0) { - if (RegRecPtr != NULL) - { - CFE_EVS_SendEventWithAppID(CFE_TBL_UPDATE_ERR_EID, CFE_EVS_EventType_ERROR, CFE_TBL_Global.TableTaskAppId, - "%s Failed to Update '%s', Status=0x%08X", AppName, RegRecPtr->Name, - (unsigned int)Status); - } - else - { - CFE_EVS_SendEventWithAppID(CFE_TBL_UPDATE_ERR_EID, CFE_EVS_EventType_ERROR, CFE_TBL_Global.TableTaskAppId, - "%s Failed to Update '?', Status=0x%08X", AppName, (unsigned int)Status); - } + /* + * Note that (Status < 0) specifically matches ERROR, not WARNING codes. The CFE_TBL_UpdateInternal() function + * currently only produces two possible codes (aside from CFE_SUCCESS) and both of these are defined as + * warnings, not errors. Therefore, its impossible to reach this code with RegRegPtr != NULL. + */ + CFE_EVS_SendEventWithAppID(CFE_TBL_UPDATE_ERR_EID, CFE_EVS_EventType_ERROR, CFE_TBL_Global.TableTaskAppId, + "%s Failed to update table, Status=0x%08X", AppName, (unsigned int)Status); } else { diff --git a/modules/tbl/fsw/src/cfe_tbl_internal.c b/modules/tbl/fsw/src/cfe_tbl_internal.c index 4672cbc10..03a1ede1e 100644 --- a/modules/tbl/fsw/src/cfe_tbl_internal.c +++ b/modules/tbl/fsw/src/cfe_tbl_internal.c @@ -1425,21 +1425,31 @@ CFE_Status_t CFE_TBL_ValidateTableName(const char *Name) *-----------------------------------------------------------------*/ CFE_Status_t CFE_TBL_ValidateTableSize(const char *Name, size_t Size, uint16 TblOptionFlags) { - CFE_Status_t Status = CFE_SUCCESS; + CFE_Status_t Status; + size_t SizeLimit; - /* Check if the specified table size is zero, or above the maximum allowed */ /* Single-buffered tables are allowed to be up to CFE_PLATFORM_TBL_MAX_SNGL_TABLE_SIZE */ /* Double-buffered tables are allowed to be up to CFE_PLATFORM_TBL_MAX_DBL_TABLE_SIZE */ - if (Size == 0 || - (Size > CFE_PLATFORM_TBL_MAX_SNGL_TABLE_SIZE && - (TblOptionFlags & CFE_TBL_OPT_BUFFER_MSK) == CFE_TBL_OPT_SNGL_BUFFER) || - (Size > CFE_PLATFORM_TBL_MAX_DBL_TABLE_SIZE && - (TblOptionFlags & CFE_TBL_OPT_BUFFER_MSK) == CFE_TBL_OPT_DBL_BUFFER)) + if ((TblOptionFlags & CFE_TBL_OPT_BUFFER_MSK) == CFE_TBL_OPT_DBL_BUFFER) + { + SizeLimit = CFE_PLATFORM_TBL_MAX_DBL_TABLE_SIZE; + } + else + { + SizeLimit = CFE_PLATFORM_TBL_MAX_SNGL_TABLE_SIZE; + } + + /* Check if the specified table size is zero, or above the maximum allowed */ + if (Size == 0 || Size > SizeLimit) { Status = CFE_TBL_ERR_INVALID_SIZE; CFE_ES_WriteToSysLog("%s: Table '%s' has invalid size (%d)\n", __func__, Name, (int)Size); } + else + { + Status = CFE_SUCCESS; + } return Status; } @@ -1719,52 +1729,53 @@ CFE_Status_t CFE_TBL_RestoreTableDataFromCDS(CFE_TBL_RegistryRec_t *RegRecPtr, c { CFE_ES_WriteToSysLog("%s: Failed to recover '%s.%s' from CDS (ErrCode=0x%08X)\n", __func__, AppName, Name, (unsigned int)Status); - } - } - if (Status != CFE_SUCCESS) - { - /* Treat a restore from existing CDS error the same as */ - /* after a power-on reset (CDS was created but is empty) */ - Status = CFE_SUCCESS; - } - else - { - /* Try to locate the associated information in the Critical Table Registry */ - CFE_TBL_FindCriticalTblInfo(&CritRegRecPtr, RegRecPtr->CDSHandle); - - if ((CritRegRecPtr != NULL) && (CritRegRecPtr->TableLoadedOnce)) + /* + * Treat a restore from existing CDS error the same as + * after a power-on reset (CDS was created but is empty) + */ + Status = CFE_SUCCESS; + } + else { - strncpy(WorkingBufferPtr->DataSource, CritRegRecPtr->LastFileLoaded, - sizeof(WorkingBufferPtr->DataSource) - 1); - WorkingBufferPtr->DataSource[sizeof(WorkingBufferPtr->DataSource) - 1] = '\0'; + /* Table was fully restored from existing CDS... */ + /* Try to locate the associated information in the Critical Table Registry */ + CFE_TBL_FindCriticalTblInfo(&CritRegRecPtr, RegRecPtr->CDSHandle); - WorkingBufferPtr->FileCreateTimeSecs = CritRegRecPtr->FileCreateTimeSecs; - WorkingBufferPtr->FileCreateTimeSubSecs = CritRegRecPtr->FileCreateTimeSubSecs; + if ((CritRegRecPtr != NULL) && (CritRegRecPtr->TableLoadedOnce)) + { + strncpy(WorkingBufferPtr->DataSource, CritRegRecPtr->LastFileLoaded, + sizeof(WorkingBufferPtr->DataSource) - 1); + WorkingBufferPtr->DataSource[sizeof(WorkingBufferPtr->DataSource) - 1] = '\0'; - strncpy(RegRecPtr->LastFileLoaded, CritRegRecPtr->LastFileLoaded, sizeof(RegRecPtr->LastFileLoaded) - 1); - RegRecPtr->LastFileLoaded[sizeof(RegRecPtr->LastFileLoaded) - 1] = '\0'; + WorkingBufferPtr->FileCreateTimeSecs = CritRegRecPtr->FileCreateTimeSecs; + WorkingBufferPtr->FileCreateTimeSubSecs = CritRegRecPtr->FileCreateTimeSubSecs; - RegRecPtr->TimeOfLastUpdate.Seconds = CritRegRecPtr->TimeOfLastUpdate.Seconds; - RegRecPtr->TimeOfLastUpdate.Subseconds = CritRegRecPtr->TimeOfLastUpdate.Subseconds; - RegRecPtr->TableLoadedOnce = CritRegRecPtr->TableLoadedOnce; + strncpy(RegRecPtr->LastFileLoaded, CritRegRecPtr->LastFileLoaded, + sizeof(RegRecPtr->LastFileLoaded) - 1); + RegRecPtr->LastFileLoaded[sizeof(RegRecPtr->LastFileLoaded) - 1] = '\0'; - /* Compute the CRC on the specified table buffer */ - WorkingBufferPtr->Crc = - CFE_ES_CalculateCRC(WorkingBufferPtr->BufferPtr, RegRecPtr->Size, 0, CFE_MISSION_ES_DEFAULT_CRC); + RegRecPtr->TimeOfLastUpdate.Seconds = CritRegRecPtr->TimeOfLastUpdate.Seconds; + RegRecPtr->TimeOfLastUpdate.Subseconds = CritRegRecPtr->TimeOfLastUpdate.Subseconds; + RegRecPtr->TableLoadedOnce = CritRegRecPtr->TableLoadedOnce; - /* Make sure everyone who sees the table knows that it has been updated */ - CFE_TBL_NotifyTblUsersOfUpdate(RegRecPtr); + /* Compute the CRC on the specified table buffer */ + WorkingBufferPtr->Crc = + CFE_ES_CalculateCRC(WorkingBufferPtr->BufferPtr, RegRecPtr->Size, 0, CFE_MISSION_ES_DEFAULT_CRC); - /* Make sure the caller realizes the contents have been initialized */ - Status = CFE_TBL_INFO_RECOVERED_TBL; - } - else - { - /* If an error occurred while trying to get the previous contents registry info, */ - /* Log the error in the System Log and pretend like we created a new CDS */ - CFE_ES_WriteToSysLog("%s: Failed to recover '%s.%s' info from CDS TblReg\n", __func__, AppName, Name); - Status = CFE_SUCCESS; + /* Make sure everyone who sees the table knows that it has been updated */ + CFE_TBL_NotifyTblUsersOfUpdate(RegRecPtr); + + /* Make sure the caller realizes the contents have been initialized */ + Status = CFE_TBL_INFO_RECOVERED_TBL; + } + else + { + /* If an error occurred while trying to get the previous contents registry info, */ + /* Log the error in the System Log and pretend like we created a new CDS */ + CFE_ES_WriteToSysLog("%s: Failed to recover '%s.%s' info from CDS TblReg\n", __func__, AppName, Name); + Status = CFE_SUCCESS; + } } } diff --git a/modules/tbl/ut-coverage/tbl_UT.c b/modules/tbl/ut-coverage/tbl_UT.c index 2f20125ab..2a3d61738 100644 --- a/modules/tbl/ut-coverage/tbl_UT.c +++ b/modules/tbl/ut-coverage/tbl_UT.c @@ -94,7 +94,7 @@ static const UT_TaskPipeDispatchId_t UT_TPID_CFE_TBL_INVALID_MID = { .Method = UT_TaskPipeDispatchMethod_MSG_ID_CC, UT_TPD_SETERR(CFE_STATUS_UNKNOWN_MSG_ID) }; static const UT_TaskPipeDispatchId_t UT_TPID_CFE_TBL_CMD_INVALID_CC = { TBL_UT_ERROR_DISPATCH(CMD, -1, CFE_STATUS_BAD_COMMAND_CODE) }; - +/* clang-format on */ CFE_TBL_RegistryRec_t Original[CFE_PLATFORM_TBL_MAX_NUM_TABLES]; @@ -3052,7 +3052,7 @@ void Test_CFE_TBL_TblMod(void) CFE_TBL_Handle_t AccessIterator; uint8 CDS_Data[sizeof(UT_Table1_t)]; uint32 ExpectedCrc; - int maxPathLenDiff = (int) CFE_MISSION_MAX_PATH_LEN - (int) OS_MAX_PATH_LEN; + int maxPathLenDiff = (int)CFE_MISSION_MAX_PATH_LEN - (int)OS_MAX_PATH_LEN; memset(&TblInfo1, 0, sizeof(TblInfo1)); @@ -3198,14 +3198,14 @@ void Test_CFE_TBL_TblMod(void) UtAssert_StrnCmp(TblInfo1.LastFileLoaded, MyFilename, sizeof(TblInfo1.LastFileLoaded) - 4, "%s == %s, %ld", TblInfo1.LastFileLoaded, MyFilename, (long)sizeof(TblInfo1.LastFileLoaded) - 4); - if(maxPathLenDiff >= 0) + if (maxPathLenDiff >= 0) { UtAssert_StrCmp(&TblInfo1.LastFileLoaded[sizeof(MyFilename) - 4], "(*)", "%s == (*)", &TblInfo1.LastFileLoaded[sizeof(MyFilename) - 4]); } - else if(maxPathLenDiff > -3) + else if (maxPathLenDiff > -3) { - int modIndicatorStart = (int) CFE_MISSION_MAX_PATH_LEN -4 - maxPathLenDiff; + int modIndicatorStart = (int)CFE_MISSION_MAX_PATH_LEN - 4 - maxPathLenDiff; UtAssert_StrCmp(&TblInfo1.LastFileLoaded[modIndicatorStart], "(*)", "%s == (*)", &TblInfo1.LastFileLoaded[modIndicatorStart]); } @@ -3957,6 +3957,37 @@ void Test_CFE_TBL_Internal(void) #else UtAssert_NA("*Not tested* Invalid processor ID "); #endif + + /* Test CFE_TBL_RestoreTableDataFromCDS() when failed to get a working buffer */ + UT_InitData(); + + RegRecPtr = &CFE_TBL_Global.Registry[0]; + + RegRecPtr->DoubleBuffered = false; + RegRecPtr->TableLoadedOnce = true; + + for (i = 0; i < CFE_PLATFORM_TBL_MAX_SIMULTANEOUS_LOADS; i++) + { + CFE_TBL_Global.LoadBuffs[i].Taken = true; + } + + UtAssert_INT32_EQ(CFE_TBL_RestoreTableDataFromCDS(RegRecPtr, "UT", "UT1", NULL), CFE_TBL_ERR_NO_BUFFER_AVAIL); + + UT_ClearEventHistory(); + + UT_InitData(); + UtAssert_INT32_EQ(CFE_TBL_ValidateTableSize("UT", 0, 0), CFE_TBL_ERR_INVALID_SIZE); + UtAssert_INT32_EQ(CFE_TBL_ValidateTableSize("UT", CFE_PLATFORM_TBL_MAX_SNGL_TABLE_SIZE, CFE_TBL_OPT_SNGL_BUFFER), + CFE_SUCCESS); + UtAssert_INT32_EQ( + CFE_TBL_ValidateTableSize("UT", CFE_PLATFORM_TBL_MAX_SNGL_TABLE_SIZE + 1, CFE_TBL_OPT_SNGL_BUFFER), + CFE_TBL_ERR_INVALID_SIZE); + UtAssert_INT32_EQ(CFE_TBL_ValidateTableSize("UT", CFE_PLATFORM_TBL_MAX_DBL_TABLE_SIZE + 1, 0), + CFE_TBL_ERR_INVALID_SIZE); + UtAssert_INT32_EQ(CFE_TBL_ValidateTableSize("UT", CFE_PLATFORM_TBL_MAX_DBL_TABLE_SIZE, CFE_TBL_OPT_DBL_BUFFER), + CFE_SUCCESS); + UtAssert_INT32_EQ(CFE_TBL_ValidateTableSize("UT", CFE_PLATFORM_TBL_MAX_DBL_TABLE_SIZE + 1, CFE_TBL_OPT_DBL_BUFFER), + CFE_TBL_ERR_INVALID_SIZE); } /* From 6087d45591f0f74b21259cb6c58b6119be1ef01d Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Wed, 20 Mar 2024 12:34:58 -0400 Subject: [PATCH 3/4] Fix #2530, naming convention for SendHkCmd Corrects name mismatches in the "SendHkCmd" implementations. ES, EVS, and TBL modules had variations on what this command was named internally in the code. --- modules/es/fsw/src/cfe_es_dispatch.c | 2 +- modules/es/fsw/src/cfe_es_task.c | 10 +++++----- modules/es/fsw/src/cfe_es_task.h | 2 +- modules/evs/fsw/src/cfe_evs_dispatch.c | 2 +- modules/evs/fsw/src/cfe_evs_task.c | 10 +++++----- modules/evs/fsw/src/cfe_evs_task.h | 2 +- modules/evs/ut-coverage/evs_UT.c | 2 +- modules/tbl/fsw/src/cfe_tbl_dispatch.c | 2 +- modules/tbl/fsw/src/cfe_tbl_task_cmds.c | 6 +++--- modules/tbl/fsw/src/cfe_tbl_task_cmds.h | 2 +- modules/tbl/ut-coverage/tbl_UT.c | 14 +++++++------- modules/tbl/ut-coverage/tbl_UT.h | 2 +- 12 files changed, 28 insertions(+), 28 deletions(-) diff --git a/modules/es/fsw/src/cfe_es_dispatch.c b/modules/es/fsw/src/cfe_es_dispatch.c index 375b6cc5a..e984e81fc 100644 --- a/modules/es/fsw/src/cfe_es_dispatch.c +++ b/modules/es/fsw/src/cfe_es_dispatch.c @@ -87,7 +87,7 @@ void CFE_ES_TaskPipe(const CFE_SB_Buffer_t *SBBufPtr) ** Housekeeping telemetry request */ case CFE_ES_SEND_HK_MID: - CFE_ES_HousekeepingCmd((const CFE_ES_SendHkCmd_t *)SBBufPtr); + CFE_ES_SendHkCmd((const CFE_ES_SendHkCmd_t *)SBBufPtr); break; /* diff --git a/modules/es/fsw/src/cfe_es_task.c b/modules/es/fsw/src/cfe_es_task.c index 02f5506c6..e7ff65b44 100644 --- a/modules/es/fsw/src/cfe_es_task.c +++ b/modules/es/fsw/src/cfe_es_task.c @@ -395,10 +395,10 @@ int32 CFE_ES_TaskInit(void) /* ** Task startup event message. */ - CFE_Config_GetVersionString(VersionString, CFE_CFG_MAX_VERSION_STR_LEN, "cFE", - CFE_SRC_VERSION, CFE_BUILD_CODENAME, CFE_LAST_OFFICIAL); - Status = CFE_EVS_SendEvent(CFE_ES_INIT_INF_EID, CFE_EVS_EventType_INFORMATION, "cFE ES Initialized: %s", - VersionString); + CFE_Config_GetVersionString(VersionString, CFE_CFG_MAX_VERSION_STR_LEN, "cFE", CFE_SRC_VERSION, CFE_BUILD_CODENAME, + CFE_LAST_OFFICIAL); + Status = + CFE_EVS_SendEvent(CFE_ES_INIT_INF_EID, CFE_EVS_EventType_INFORMATION, "cFE ES Initialized: %s", VersionString); if (Status != CFE_SUCCESS) { CFE_ES_WriteToSysLog("%s: Error sending init event:RC=0x%08X\n", __func__, (unsigned int)Status); @@ -443,7 +443,7 @@ int32 CFE_ES_TaskInit(void) * See description in header file for argument/return detail * *-----------------------------------------------------------------*/ -int32 CFE_ES_HousekeepingCmd(const CFE_ES_SendHkCmd_t *data) +int32 CFE_ES_SendHkCmd(const CFE_ES_SendHkCmd_t *data) { OS_heap_prop_t HeapProp; int32 OsStatus; diff --git a/modules/es/fsw/src/cfe_es_task.h b/modules/es/fsw/src/cfe_es_task.h index 54bf57a0a..7784ed6e1 100644 --- a/modules/es/fsw/src/cfe_es_task.h +++ b/modules/es/fsw/src/cfe_es_task.h @@ -122,7 +122,7 @@ void CFE_ES_BackgroundCleanup(void); /* ** ES Task message dispatch functions */ -int32 CFE_ES_HousekeepingCmd(const CFE_ES_SendHkCmd_t *data); +int32 CFE_ES_SendHkCmd(const CFE_ES_SendHkCmd_t *data); /*---------------------------------------------------------------------------------------*/ /** diff --git a/modules/evs/fsw/src/cfe_evs_dispatch.c b/modules/evs/fsw/src/cfe_evs_dispatch.c index 53ee28f71..9d43bfc29 100644 --- a/modules/evs/fsw/src/cfe_evs_dispatch.c +++ b/modules/evs/fsw/src/cfe_evs_dispatch.c @@ -55,7 +55,7 @@ void CFE_EVS_ProcessCommandPacket(const CFE_SB_Buffer_t *SBBufPtr) case CFE_EVS_SEND_HK_MID: /* Housekeeping request */ - CFE_EVS_ReportHousekeepingCmd((const CFE_EVS_SendHkCmd_t *)SBBufPtr); + CFE_EVS_SendHkCmd((const CFE_EVS_SendHkCmd_t *)SBBufPtr); break; default: diff --git a/modules/evs/fsw/src/cfe_evs_task.c b/modules/evs/fsw/src/cfe_evs_task.c index 59e8c1ce4..539fe532c 100644 --- a/modules/evs/fsw/src/cfe_evs_task.c +++ b/modules/evs/fsw/src/cfe_evs_task.c @@ -298,8 +298,8 @@ int32 CFE_EVS_TaskInit(void) /* Write the AppID to the global location, now that the rest of initialization is done */ CFE_EVS_Global.EVS_AppID = AppID; - CFE_Config_GetVersionString(VersionString, CFE_CFG_MAX_VERSION_STR_LEN, "cFE", - CFE_SRC_VERSION, CFE_BUILD_CODENAME, CFE_LAST_OFFICIAL); + CFE_Config_GetVersionString(VersionString, CFE_CFG_MAX_VERSION_STR_LEN, "cFE", CFE_SRC_VERSION, CFE_BUILD_CODENAME, + CFE_LAST_OFFICIAL); EVS_SendEvent(CFE_EVS_STARTUP_EID, CFE_EVS_EventType_INFORMATION, "cFE EVS Initialized: %s", VersionString); return CFE_SUCCESS; @@ -314,8 +314,8 @@ int32 CFE_EVS_TaskInit(void) int32 CFE_EVS_NoopCmd(const CFE_EVS_NoopCmd_t *data) { char VersionString[CFE_CFG_MAX_VERSION_STR_LEN]; - CFE_Config_GetVersionString(VersionString, CFE_CFG_MAX_VERSION_STR_LEN, "cFE", - CFE_SRC_VERSION, CFE_BUILD_CODENAME, CFE_LAST_OFFICIAL); + CFE_Config_GetVersionString(VersionString, CFE_CFG_MAX_VERSION_STR_LEN, "cFE", CFE_SRC_VERSION, CFE_BUILD_CODENAME, + CFE_LAST_OFFICIAL); EVS_SendEvent(CFE_EVS_NOOP_EID, CFE_EVS_EventType_INFORMATION, "No-op Cmd Rcvd: %s", VersionString); return CFE_SUCCESS; } @@ -338,7 +338,7 @@ int32 CFE_EVS_ClearLogCmd(const CFE_EVS_ClearLogCmd_t *data) * See description in header file for argument/return detail * *-----------------------------------------------------------------*/ -int32 CFE_EVS_ReportHousekeepingCmd(const CFE_EVS_SendHkCmd_t *data) +int32 CFE_EVS_SendHkCmd(const CFE_EVS_SendHkCmd_t *data) { uint32 i, j; EVS_AppData_t * AppDataPtr; diff --git a/modules/evs/fsw/src/cfe_evs_task.h b/modules/evs/fsw/src/cfe_evs_task.h index bd111c7a8..e765adecd 100644 --- a/modules/evs/fsw/src/cfe_evs_task.h +++ b/modules/evs/fsw/src/cfe_evs_task.h @@ -153,7 +153,7 @@ int32 CFE_EVS_TaskInit(void); * * Request for housekeeping status telemetry packet. */ -int32 CFE_EVS_ReportHousekeepingCmd(const CFE_EVS_SendHkCmd_t *data); +int32 CFE_EVS_SendHkCmd(const CFE_EVS_SendHkCmd_t *data); /*---------------------------------------------------------------------------------------*/ /** diff --git a/modules/evs/ut-coverage/evs_UT.c b/modules/evs/ut-coverage/evs_UT.c index f100b8f1b..fa42ae1ea 100644 --- a/modules/evs/ut-coverage/evs_UT.c +++ b/modules/evs/ut-coverage/evs_UT.c @@ -2139,5 +2139,5 @@ void Test_Misc(void) /* Doesn't matter here that AppID is all the same... */ EVS_AppDataSetUsed(&CFE_EVS_Global.AppData[i], AppID); } - UtAssert_UINT32_EQ(CFE_EVS_ReportHousekeepingCmd(NULL), CFE_STATUS_NO_COUNTER_INCREMENT); + UtAssert_UINT32_EQ(CFE_EVS_SendHkCmd(NULL), CFE_STATUS_NO_COUNTER_INCREMENT); } diff --git a/modules/tbl/fsw/src/cfe_tbl_dispatch.c b/modules/tbl/fsw/src/cfe_tbl_dispatch.c index 4b2a57771..ecc741e1e 100644 --- a/modules/tbl/fsw/src/cfe_tbl_dispatch.c +++ b/modules/tbl/fsw/src/cfe_tbl_dispatch.c @@ -59,7 +59,7 @@ typedef struct const CFE_TBL_CmdHandlerTblRec_t CFE_TBL_CmdHandlerTbl[] = { /* SEND_HK Entry */ - CFE_TBL_ENTRY(CFE_TBL_SEND_HK_MID, 0, CFE_TBL_SendHkCmd_t, CFE_TBL_HousekeepingCmd, CFE_TBL_MSG_MSGTYPE), + CFE_TBL_ENTRY(CFE_TBL_SEND_HK_MID, 0, CFE_TBL_SendHkCmd_t, CFE_TBL_SendHkCmd, CFE_TBL_MSG_MSGTYPE), /* Everything else */ CFE_TBL_ENTRY(CFE_TBL_CMD_MID, CFE_TBL_NOOP_CC, CFE_TBL_NoopCmd_t, CFE_TBL_NoopCmd, CFE_TBL_CMD_MSGTYPE), diff --git a/modules/tbl/fsw/src/cfe_tbl_task_cmds.c b/modules/tbl/fsw/src/cfe_tbl_task_cmds.c index 28d87c652..832f05045 100644 --- a/modules/tbl/fsw/src/cfe_tbl_task_cmds.c +++ b/modules/tbl/fsw/src/cfe_tbl_task_cmds.c @@ -42,7 +42,7 @@ * See description in header file for argument/return detail * *-----------------------------------------------------------------*/ -int32 CFE_TBL_HousekeepingCmd(const CFE_MSG_CommandHeader_t *data) +int32 CFE_TBL_SendHkCmd(const CFE_TBL_SendHkCmd_t *data) { int32 Status; int32 OsStatus; @@ -314,8 +314,8 @@ int32 CFE_TBL_NoopCmd(const CFE_TBL_NoopCmd_t *data) char VersionString[CFE_CFG_MAX_VERSION_STR_LEN]; /* Acknowledge receipt of NOOP with Event Message */ - CFE_Config_GetVersionString(VersionString, CFE_CFG_MAX_VERSION_STR_LEN, "cFE", - CFE_SRC_VERSION, CFE_BUILD_CODENAME, CFE_LAST_OFFICIAL); + CFE_Config_GetVersionString(VersionString, CFE_CFG_MAX_VERSION_STR_LEN, "cFE", CFE_SRC_VERSION, CFE_BUILD_CODENAME, + CFE_LAST_OFFICIAL); CFE_EVS_SendEvent(CFE_TBL_NOOP_INF_EID, CFE_EVS_EventType_INFORMATION, "No-op Cmd Rcvd: %s", VersionString); return CFE_TBL_INC_CMD_CTR; diff --git a/modules/tbl/fsw/src/cfe_tbl_task_cmds.h b/modules/tbl/fsw/src/cfe_tbl_task_cmds.h index 1dfd63a5a..93dbd9214 100644 --- a/modules/tbl/fsw/src/cfe_tbl_task_cmds.h +++ b/modules/tbl/fsw/src/cfe_tbl_task_cmds.h @@ -121,7 +121,7 @@ void CFE_TBL_GetTblRegData(void); ** ** \retval #CFE_TBL_DONT_INC_CTR \copydoc CFE_TBL_DONT_INC_CTR */ -int32 CFE_TBL_HousekeepingCmd(const CFE_MSG_CommandHeader_t *data); +int32 CFE_TBL_SendHkCmd(const CFE_TBL_SendHkCmd_t *data); /*---------------------------------------------------------------------------------------*/ /** diff --git a/modules/tbl/ut-coverage/tbl_UT.c b/modules/tbl/ut-coverage/tbl_UT.c index 2f20125ab..300c54451 100644 --- a/modules/tbl/ut-coverage/tbl_UT.c +++ b/modules/tbl/ut-coverage/tbl_UT.c @@ -143,7 +143,7 @@ void UtTest_Setup(void) UT_ADD_TEST(Test_CFE_TBL_DumpRegCmd); UT_ADD_TEST(Test_CFE_TBL_DumpCmd); UT_ADD_TEST(Test_CFE_TBL_LoadCmd); - UT_ADD_TEST(Test_CFE_TBL_HousekeepingCmd); + UT_ADD_TEST(Test_CFE_TBL_SendHkCmd); /* cfe_tbl_api.c and cfe_tbl_internal.c functions */ UT_ADD_TEST(Test_CFE_TBL_ApiInit); @@ -1319,7 +1319,7 @@ void Test_CFE_TBL_LoadCmd(void) /* ** Test the function that processes housekeeping request message */ -void Test_CFE_TBL_HousekeepingCmd(void) +void Test_CFE_TBL_SendHkCmd(void) { int i; CFE_TBL_LoadBuff_t DumpBuff; @@ -1361,7 +1361,7 @@ void Test_CFE_TBL_HousekeepingCmd(void) UT_SetDeferredRetcode(UT_KEY(CFE_SB_TransmitMsg), 1, CFE_SUCCESS - 1); CFE_TBL_Global.HkTlmTblRegIndex = CFE_TBL_NOT_FOUND + 1; - UtAssert_INT32_EQ(CFE_TBL_HousekeepingCmd(NULL), CFE_TBL_DONT_INC_CTR); + UtAssert_INT32_EQ(CFE_TBL_SendHkCmd(NULL), CFE_TBL_DONT_INC_CTR); for (i = 1; i < CFE_PLATFORM_TBL_MAX_SIMULTANEOUS_LOADS; i++) { @@ -1376,26 +1376,26 @@ void Test_CFE_TBL_HousekeepingCmd(void) CFE_TBL_Global.DumpControlBlocks[0].State = CFE_TBL_DUMP_PERFORMED; CFE_TBL_Global.HkTlmTblRegIndex = CFE_TBL_NOT_FOUND + 1; UT_SetDefaultReturnValue(UT_KEY(OS_OpenCreate), OS_ERROR); - UtAssert_INT32_EQ(CFE_TBL_HousekeepingCmd(NULL), CFE_TBL_DONT_INC_CTR); + UtAssert_INT32_EQ(CFE_TBL_SendHkCmd(NULL), CFE_TBL_DONT_INC_CTR); /* Test response to an invalid table and a dump file create failure */ UT_InitData(); CFE_TBL_Global.HkTlmTblRegIndex = CFE_TBL_NOT_FOUND; CFE_TBL_Global.DumpControlBlocks[0].State = CFE_TBL_DUMP_PERFORMED; UT_SetDefaultReturnValue(UT_KEY(OS_OpenCreate), OS_ERROR); - UtAssert_INT32_EQ(CFE_TBL_HousekeepingCmd(NULL), CFE_TBL_DONT_INC_CTR); + UtAssert_INT32_EQ(CFE_TBL_SendHkCmd(NULL), CFE_TBL_DONT_INC_CTR); /* Test response to a file time stamp failure */ UT_InitData(); CFE_TBL_Global.DumpControlBlocks[0].State = CFE_TBL_DUMP_PERFORMED; UT_SetDeferredRetcode(UT_KEY(CFE_FS_SetTimestamp), 1, OS_SUCCESS - 1); - UtAssert_INT32_EQ(CFE_TBL_HousekeepingCmd(NULL), CFE_TBL_DONT_INC_CTR); + UtAssert_INT32_EQ(CFE_TBL_SendHkCmd(NULL), CFE_TBL_DONT_INC_CTR); /* Test response to OS_OpenCreate failure */ UT_InitData(); CFE_TBL_Global.DumpControlBlocks[0].State = CFE_TBL_DUMP_PERFORMED; UT_SetDeferredRetcode(UT_KEY(OS_OpenCreate), 3, -1); - UtAssert_INT32_EQ(CFE_TBL_HousekeepingCmd(NULL), CFE_TBL_DONT_INC_CTR); + UtAssert_INT32_EQ(CFE_TBL_SendHkCmd(NULL), CFE_TBL_DONT_INC_CTR); } /* diff --git a/modules/tbl/ut-coverage/tbl_UT.h b/modules/tbl/ut-coverage/tbl_UT.h index ae0796d12..d4f2d80c7 100644 --- a/modules/tbl/ut-coverage/tbl_UT.h +++ b/modules/tbl/ut-coverage/tbl_UT.h @@ -359,7 +359,7 @@ void Test_CFE_TBL_LoadCmd(void); ** \returns ** This function does not return a value. ******************************************************************************/ -void Test_CFE_TBL_HousekeepingCmd(void); +void Test_CFE_TBL_SendHkCmd(void); /*****************************************************************************/ /** From c794cdb4cfce896db35cd730ba180083cb1c2719 Mon Sep 17 00:00:00 2001 From: Dylan Date: Thu, 21 Mar 2024 15:58:17 -0400 Subject: [PATCH 4/4] Updating documentation and version numbers for equuleus-rc1+dev114 --- CHANGELOG.md | 5 +++++ modules/core_api/fsw/inc/cfe_version.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a1c5266c..3fc22b499 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## Development Build: equuleus-rc1+dev114 +- Split up and simplify control flow in CFE_TBL_Register() +- naming convention for SendHkCmd +- See and + ## Development Build: equuleus-rc1+dev107 - propagate stack pointer for child tasks - add missing memset() for stack variables diff --git a/modules/core_api/fsw/inc/cfe_version.h b/modules/core_api/fsw/inc/cfe_version.h index 2dc8fdc0b..a7517d24f 100644 --- a/modules/core_api/fsw/inc/cfe_version.h +++ b/modules/core_api/fsw/inc/cfe_version.h @@ -26,7 +26,7 @@ #define CFE_VERSION_H /* Development Build Macro Definitions */ -#define CFE_BUILD_NUMBER 107 /**< @brief Development: Number of development git commits since CFE_BUILD_BASELINE */ +#define CFE_BUILD_NUMBER 114 /**< @brief Development: Number of development git commits since CFE_BUILD_BASELINE */ #define CFE_BUILD_BASELINE "equuleus-rc1" /**< @brief Development: Reference git tag for build number */ #define CFE_BUILD_DEV_CYCLE "equuleus-rc2" /**< @brief Development: Release name for current development cycle */ #define CFE_BUILD_CODENAME "Equuleus" /**< @brief: Development: Code name for the current build */