From b17cd1e3394efe061bc58c76cf6424e96d1c2fc4 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Tue, 12 Jan 2021 17:21:38 -0500 Subject: [PATCH] Fix #1073, refactor SB API for proper global locks Significant refactor of many SB API calls to address inconsistencies with respect to locking and unlocking of global data structures. First this updates the definition of CFE_SB_PipeId_t to use the CFE_ES_ResourceID_t base type, and a new ID range. Notably this prevents direct access to the CFE_SB.PipeTbl global, forcing code to go through the proper lookup routine, which should only be done while locked. All API implementations follow the same general pattern: - Initial checks/queries while unlocked - Lock SB global - Lookups and/or modifications to the pipe table/routing info - Unlock SB global - Invoke other subsystems (e.g. OSAL) - Re-lock SB global (if needed) do final update, and unlock again - Send all events All error counters should be updated at the end, while still locked. All event processing is deferred to the end of each function, after all other processing is done. --- fsw/cfe-core/src/inc/cfe_sb.h | 36 +- fsw/cfe-core/src/inc/cfe_sb_msg.h | 4 +- .../src/inc/private/cfe_resourceid_internal.h | 5 + fsw/cfe-core/src/sb/cfe_sb_api.c | 1985 ++++++++++------- fsw/cfe-core/src/sb/cfe_sb_buf.c | 46 +- fsw/cfe-core/src/sb/cfe_sb_init.c | 16 +- fsw/cfe-core/src/sb/cfe_sb_priv.c | 187 +- fsw/cfe-core/src/sb/cfe_sb_priv.h | 133 +- fsw/cfe-core/src/sb/cfe_sb_task.c | 360 ++- fsw/cfe-core/src/time/cfe_time_tone.c | 2 +- fsw/cfe-core/unit-test/sb_UT.c | 299 +-- fsw/cfe-core/unit-test/sb_UT.h | 17 - fsw/cfe-core/ut-stubs/ut_sb_stubs.c | 2 +- 13 files changed, 1852 insertions(+), 1240 deletions(-) diff --git a/fsw/cfe-core/src/inc/cfe_sb.h b/fsw/cfe-core/src/inc/cfe_sb.h index 2d01e1ef3..e5073b506 100644 --- a/fsw/cfe-core/src/inc/cfe_sb.h +++ b/fsw/cfe-core/src/inc/cfe_sb.h @@ -43,6 +43,7 @@ #include "cfe_mission_cfg.h" #include "ccsds.h" #include "cfe_time.h" +#include "cfe_resourceid.h" /* @@ -122,6 +123,13 @@ #define CFE_CLR(i,x) ((i) &= ~CFE_BIT(x)) /**< \brief Clears bit x of i */ #define CFE_TST(i,x) (((i) & CFE_BIT(x)) != 0)/**< \brief true(non zero) if bit x of i is set */ +/** + * \brief A CFE_SB_PipeId_t value which is always invalid + * + * This may be used as a safe initializer for CFE_SB_PipeId_t values + */ +#define CFE_SB_INVALID_PIPE CFE_ES_RESOURCEID_UNDEFINED + /* ** Pipe option bit fields. */ @@ -156,7 +164,7 @@ typedef CFE_MSG_TelemetryHeader_t CFE_SB_TlmHdr_t; ** ** Software Bus pipe identifier used in many SB APIs */ -typedef uint8 CFE_SB_PipeId_t; +typedef CFE_ES_ResourceID_t CFE_SB_PipeId_t; #ifndef CFE_OMIT_DEPRECATED_6_8 /** \brief Pointer to an SB Message */ @@ -256,6 +264,32 @@ CFE_Status_t CFE_SB_CreatePipe(CFE_SB_PipeId_t *PipeIdPtr, uint16 Depth, const **/ CFE_Status_t CFE_SB_DeletePipe(CFE_SB_PipeId_t PipeId); +/** + * @brief Obtain an index value correlating to an SB Pipe ID + * + * This calculates a zero based integer value that may be used for indexing + * into a local resource table/array. + * + * Index values are only guaranteed to be unique for resources of the same + * type. For instance, the indices corresponding to two [valid] application + * IDs will never overlap, but the index of a pipe ID and an app ID + * may be the same. Furthermore, indices may be reused if a resource is + * deleted and re-created. + * + * @note There is no inverse of this function - indices cannot be converted + * back to the original PipeID value. The caller should retain the original ID + * for future use. + * + * @param[in] PipeID Pipe ID to convert + * @param[out] Idx Buffer where the calculated index will be stored + * + * @return Execution status, see @ref CFEReturnCodes + * @retval #CFE_SUCCESS @copybrief CFE_SUCCESS + * @retval #CFE_ES_ERR_RESOURCEID_NOT_VALID @copybrief CFE_ES_ERR_RESOURCEID_NOT_VALID + */ +CFE_Status_t CFE_SB_PipeId_ToIndex(CFE_SB_PipeId_t PipeID, uint32 *Idx); + + /*****************************************************************************/ /** ** \brief Set options on a pipe. diff --git a/fsw/cfe-core/src/inc/cfe_sb_msg.h b/fsw/cfe-core/src/inc/cfe_sb_msg.h index cdf37ccef..40623ad8d 100644 --- a/fsw/cfe-core/src/inc/cfe_sb_msg.h +++ b/fsw/cfe-core/src/inc/cfe_sb_msg.h @@ -604,14 +604,14 @@ typedef struct CFE_SB_PipeDepthStats { CFE_SB_PipeId_t PipeId;/**< \cfetlmmnemonic \SB_PDPIPEID \brief Pipe Id associated with the stats below */ - uint8 Spare;/**< \cfetlmmnemonic \SB_PDSPARE - \brief Spare byte to ensure alignment */ uint16 Depth;/**< \cfetlmmnemonic \SB_PDDEPTH \brief Number of messages the pipe can hold */ uint16 InUse;/**< \cfetlmmnemonic \SB_PDINUSE \brief Number of messages currently on the pipe */ uint16 PeakInUse;/**< \cfetlmmnemonic \SB_PDPKINUSE \brief Peak number of messages that have been on the pipe */ + uint16 Spare;/**< \cfetlmmnemonic \SB_PDSPARE + \brief Spare word to ensure alignment */ }CFE_SB_PipeDepthStats_t; diff --git a/fsw/cfe-core/src/inc/private/cfe_resourceid_internal.h b/fsw/cfe-core/src/inc/private/cfe_resourceid_internal.h index 614bbe76f..cf9969fa7 100644 --- a/fsw/cfe-core/src/inc/private/cfe_resourceid_internal.h +++ b/fsw/cfe-core/src/inc/private/cfe_resourceid_internal.h @@ -60,12 +60,17 @@ * @defgroup CFEResourceIDBase Resource ID base values * @{ */ + +/* ES managed resources */ #define CFE_ES_APPID_BASE (CFE_ES_RESOURCEID_MARK | ((OS_OBJECT_TYPE_USER+1) << CFE_ES_RESOURCEID_SHIFT)) #define CFE_ES_LIBID_BASE (CFE_ES_RESOURCEID_MARK | ((OS_OBJECT_TYPE_USER+2) << CFE_ES_RESOURCEID_SHIFT)) #define CFE_ES_COUNTID_BASE (CFE_ES_RESOURCEID_MARK | ((OS_OBJECT_TYPE_USER+3) << CFE_ES_RESOURCEID_SHIFT)) #define CFE_ES_POOLID_BASE (CFE_ES_RESOURCEID_MARK | ((OS_OBJECT_TYPE_USER+4) << CFE_ES_RESOURCEID_SHIFT)) #define CFE_ES_CDSBLOCKID_BASE (CFE_ES_RESOURCEID_MARK | ((OS_OBJECT_TYPE_USER+5) << CFE_ES_RESOURCEID_SHIFT)) +/* SB managed resources */ +#define CFE_SB_PIPEID_BASE (CFE_ES_RESOURCEID_MARK | ((OS_OBJECT_TYPE_USER+6) << CFE_ES_RESOURCEID_SHIFT)) + /** @} */ diff --git a/fsw/cfe-core/src/sb/cfe_sb_api.c b/fsw/cfe-core/src/sb/cfe_sb_api.c index f05161ad1..f4a8cdcf8 100644 --- a/fsw/cfe-core/src/sb/cfe_sb_api.c +++ b/fsw/cfe-core/src/sb/cfe_sb_api.c @@ -82,6 +82,18 @@ typedef struct CFE_SB_PipeId_t PipeId; /* Pipe id to remove */ } CFE_SB_RemovePipeCallback_t; + +/* + * Function: CFE_SB_PipeId_ToIndex - See API and header file for details + */ +CFE_Status_t CFE_SB_PipeId_ToIndex(CFE_SB_PipeId_t PipeID, uint32 *Idx) +{ + return CFE_ES_ResourceID_ToIndex( + CFE_ES_ResourceID_ToInteger(PipeID) - CFE_SB_PIPEID_BASE, + CFE_PLATFORM_SB_MAX_PIPES, + Idx); +} + /* * Function: CFE_SB_CreatePipe - See API and header file for details */ @@ -91,123 +103,185 @@ int32 CFE_SB_CreatePipe(CFE_SB_PipeId_t *PipeIdPtr, uint16 Depth, const char * CFE_ES_ResourceID_t TskId; osal_id_t SysQueueId; int32 Status; - CFE_SB_PipeId_t OriginalPipeIdParamValue = (PipeIdPtr == NULL) ? 0 : (*PipeIdPtr); - CFE_SB_PipeId_t PipeTblIdx; - char AppName[OS_MAX_API_NAME] = {'\0'}; + CFE_SB_PipeD_t *PipeDscPtr; + CFE_SB_PipeId_t PendingPipeId; + uint16 PendingEventId; char FullName[(OS_MAX_API_NAME * 2)]; - /* get callers AppId */ + Status = CFE_SUCCESS; + SysQueueId = OS_OBJECT_ID_UNDEFINED; + PendingEventId = 0; + PipeDscPtr = NULL; + + /* + * Get caller AppId. + * + * This is needed for both success and failure cases, + * as it is stored in the Pipe Descriptor on success, + * and used for events on failure, so get it now. + */ CFE_ES_GetAppID(&AppId); /* get callers TaskId */ CFE_ES_GetTaskID(&TskId); - /* get callers name */ - CFE_ES_GetAppName(AppName, AppId, sizeof(AppName)); + /* check input parameters */ + if((PipeIdPtr == NULL) || (Depth > CFE_PLATFORM_SB_MAX_PIPE_DEPTH) || (Depth == 0)) + { + PendingEventId = CFE_SB_CR_PIPE_BAD_ARG_EID; + Status = CFE_SB_BAD_ARGUMENT; + } + else + { + /* Get an available Pipe Descriptor which must be done while locked */ + CFE_SB_LockSharedData(__func__,__LINE__); - /* Hardcode a NULL terminator, in case rcvd name was too long */ - AppName[OS_MAX_API_NAME-1]= '\0'; + /* get first available entry in pipe table */ + PendingPipeId = CFE_ES_FindNextAvailableId(CFE_SB.LastPipeId, CFE_PLATFORM_SB_MAX_PIPES, CFE_SB_CheckPipeDescSlotUsed); + PipeDscPtr = CFE_SB_LocatePipeDescByID(PendingPipeId); - /* take semaphore to prevent a task switch during this call */ - CFE_SB_LockSharedData(__func__,__LINE__); + /* if pipe table is full, send event and return error */ + if(PipeDscPtr == NULL) + { + PendingEventId = CFE_SB_MAX_PIPES_MET_EID; + Status = CFE_SB_MAX_PIPES_MET; + } + else + { + /* Fully clear the entry, just in case of stale data */ + memset(PipeDscPtr, 0, sizeof(*PipeDscPtr)); - /* set user's pipe id value to 'invalid' for error cases below */ - if(PipeIdPtr != NULL){ - *PipeIdPtr = CFE_SB_INVALID_PIPE; - }/* end if */ + CFE_SB_PipeDescSetUsed(PipeDscPtr, CFE_ES_RESOURCEID_RESERVED); + CFE_SB.LastPipeId = PendingPipeId; + } - /* check input parameters */ - if((PipeIdPtr == NULL)||(Depth > CFE_PLATFORM_SB_MAX_PIPE_DEPTH)||(Depth == 0)){ - CFE_SB.HKTlmMsg.Payload.CreatePipeErrorCounter++; CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_CR_PIPE_BAD_ARG_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "CreatePipeErr:Bad Input Arg:app=%s,ptr=0x%lx,depth=%d,maxdepth=%d", - CFE_SB_GetAppTskName(TskId,FullName),(unsigned long)PipeIdPtr,(int)Depth,CFE_PLATFORM_SB_MAX_PIPE_DEPTH); - return CFE_SB_BAD_ARGUMENT; - }/*end if*/ + } - /* get first available entry in pipe table */ - PipeTblIdx = CFE_SB_GetAvailPipeIdx(); + if (Status == CFE_SUCCESS) + { + /* create the queue */ + Status = OS_QueueCreate(&SysQueueId,PipeName,Depth,sizeof(CFE_SB_BufferD_t *),0); + if (Status == OS_SUCCESS) + { + /* just translate the RC to CFE */ + Status = CFE_SUCCESS; + } + else + { + if (Status == OS_ERR_NAME_TAKEN) + { + PendingEventId = CFE_SB_CR_PIPE_NAME_TAKEN_EID; + } + else if (Status == OS_ERR_NO_FREE_IDS) + { + PendingEventId = CFE_SB_CR_PIPE_NO_FREE_EID; + } + else + { + /* some other unexpected error */ + PendingEventId = CFE_SB_CR_PIPE_ERR_EID; + } - /* if pipe table is full, send event and return error */ - if(PipeTblIdx == CFE_SB_INVALID_PIPE){ - CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_MAX_PIPES_MET_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "CreatePipeErr:Max Pipes(%d)In Use.app %s", - CFE_PLATFORM_SB_MAX_PIPES,CFE_SB_GetAppTskName(TskId,FullName)); - return CFE_SB_MAX_PIPES_MET; - }/* end if */ + /* translate OSAL error to CFE error code */ + Status = CFE_SB_PIPE_CR_ERR; + } + } - /* create the queue */ - Status = OS_QueueCreate(&SysQueueId,PipeName,Depth,sizeof(CFE_SB_BufferD_t *),0); - if (Status != OS_SUCCESS) { - CFE_SB_UnlockSharedData(__func__,__LINE__); + CFE_SB_LockSharedData(__func__,__LINE__); - /* if OS_QueueCreate() failed because the pipe name passed in was already in use... */ - /* let's make sure we don't alter the user's pipe ID data */ - switch(Status) { - case OS_ERR_NAME_TAKEN: - CFE_EVS_SendEventWithAppID(CFE_SB_CR_PIPE_NAME_TAKEN_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "CreatePipeErr:OS_QueueCreate failed, name taken (app=%s, name=%s)", - CFE_SB_GetAppTskName(TskId,FullName), PipeName); + if (Status == CFE_SUCCESS) + { + /* fill in the pipe table fields */ + PipeDscPtr->SysQueueId = SysQueueId; + PipeDscPtr->QueueDepth = Depth; + PipeDscPtr->AppId = AppId; - *PipeIdPtr = OriginalPipeIdParamValue; + CFE_SB_PipeDescSetUsed(PipeDscPtr, PendingPipeId); - break; - case OS_ERR_NO_FREE_IDS: - CFE_EVS_SendEventWithAppID(CFE_SB_CR_PIPE_NO_FREE_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "CreatePipeErr:OS_QueueCreate failed, no free id's (app=%s)", - CFE_SB_GetAppTskName(TskId,FullName)); + /* Increment the Pipes in use ctr and if it's > the high water mark,*/ + /* adjust the high water mark */ + CFE_SB.StatTlmMsg.Payload.PipesInUse++; + if (CFE_SB.StatTlmMsg.Payload.PipesInUse > CFE_SB.StatTlmMsg.Payload.PeakPipesInUse) + { + CFE_SB.StatTlmMsg.Payload.PeakPipesInUse = CFE_SB.StatTlmMsg.Payload.PipesInUse; + }/* end if */ + } + else + { + /* + * If a descriptor had been allocated, then free it. + */ + if (PipeDscPtr != NULL) + { + CFE_SB_PipeDescSetFree(PipeDscPtr); + PipeDscPtr = NULL; + } + PendingPipeId = CFE_ES_RESOURCEID_UNDEFINED; + /* + * If there is a relevant error counter, increment it now + * while the global data is locked. + */ + switch(PendingEventId) + { + case CFE_SB_CR_PIPE_BAD_ARG_EID: + ++CFE_SB.HKTlmMsg.Payload.CreatePipeErrorCounter; break; default: - CFE_EVS_SendEventWithAppID(CFE_SB_CR_PIPE_ERR_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "CreatePipeErr:OS_QueueCreate returned %d,app %s", - (int)Status,CFE_SB_GetAppTskName(TskId,FullName)); - }/* end switch(Status) */ - - return CFE_SB_PIPE_CR_ERR; - }/* end if */ + /* no counter */ + break; + } + } - /* fill in the pipe table fields */ - CFE_SB.PipeTbl[PipeTblIdx].InUse = CFE_SB_IN_USE; - CFE_SB.PipeTbl[PipeTblIdx].SysQueueId = SysQueueId; - CFE_SB.PipeTbl[PipeTblIdx].PipeId = PipeTblIdx; - CFE_SB.PipeTbl[PipeTblIdx].QueueDepth = Depth; - CFE_SB.PipeTbl[PipeTblIdx].AppId = AppId; - CFE_SB.PipeTbl[PipeTblIdx].SendErrors = 0; - CFE_SB.PipeTbl[PipeTblIdx].CurrentBuff = NULL; - CFE_SB.PipeTbl[PipeTblIdx].ToTrashBuff = NULL; - strcpy(&CFE_SB.PipeTbl[PipeTblIdx].AppName[0],&AppName[0]); - - /* Increment the Pipes in use ctr and if it's > the high water mark,*/ - /* adjust the high water mark */ - CFE_SB.StatTlmMsg.Payload.PipesInUse++; - if(CFE_SB.StatTlmMsg.Payload.PipesInUse > CFE_SB.StatTlmMsg.Payload.PeakPipesInUse){ - CFE_SB.StatTlmMsg.Payload.PeakPipesInUse = CFE_SB.StatTlmMsg.Payload.PipesInUse; - }/* end if */ + CFE_SB_UnlockSharedData(__func__,__LINE__); - /* Reset the pipe depth parameters in the statistics pkt */ - if (PipeTblIdx < CFE_SB_TLM_PIPEDEPTHSTATS_SIZE) + /* Send any pending events now, after final unlock */ + if (Status == CFE_SUCCESS) { - CFE_SB.StatTlmMsg.Payload.PipeDepthStats[PipeTblIdx].PipeId = PipeTblIdx; - CFE_SB.StatTlmMsg.Payload.PipeDepthStats[PipeTblIdx].Depth = Depth; - CFE_SB.StatTlmMsg.Payload.PipeDepthStats[PipeTblIdx].InUse = 0; - CFE_SB.StatTlmMsg.Payload.PipeDepthStats[PipeTblIdx].PeakInUse = 0; - } - - /* give the pipe handle to the caller */ - *PipeIdPtr = PipeTblIdx; + /* send debug event */ + CFE_EVS_SendEventWithAppID(CFE_SB_PIPE_ADDED_EID,CFE_EVS_EventType_DEBUG,CFE_SB.AppId, + "Pipe Created:name %s,id %d,app %s", + PipeName, (int)CFE_ES_ResourceID_ToInteger(PendingPipeId), + CFE_SB_GetAppTskName(TskId,FullName)); - CFE_SB_UnlockSharedData(__func__,__LINE__); + /* give the pipe handle to the caller */ + *PipeIdPtr = PendingPipeId; + } + else + { + switch(PendingEventId) + { + case CFE_SB_CR_PIPE_BAD_ARG_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_CR_PIPE_BAD_ARG_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "CreatePipeErr:Bad Input Arg:app=%s,ptr=0x%lx,depth=%d,maxdepth=%d", + CFE_SB_GetAppTskName(TskId,FullName),(unsigned long)PipeIdPtr,(int)Depth,CFE_PLATFORM_SB_MAX_PIPE_DEPTH); + break; - /* send debug event */ - CFE_EVS_SendEventWithAppID(CFE_SB_PIPE_ADDED_EID,CFE_EVS_EventType_DEBUG,CFE_SB.AppId, - "Pipe Created:name %s,id %d,app %s", - PipeName, (int)CFE_SB.PipeTbl[PipeTblIdx].PipeId, - CFE_SB_GetAppTskName(TskId,FullName)); + case CFE_SB_MAX_PIPES_MET_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_MAX_PIPES_MET_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "CreatePipeErr:Max Pipes(%d)In Use.app %s", + CFE_PLATFORM_SB_MAX_PIPES,CFE_SB_GetAppTskName(TskId,FullName)); + break; + case CFE_SB_CR_PIPE_NAME_TAKEN_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_CR_PIPE_NAME_TAKEN_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "CreatePipeErr:OS_QueueCreate failed, name taken (app=%s, name=%s)", + CFE_SB_GetAppTskName(TskId,FullName), PipeName); + break; + case CFE_SB_CR_PIPE_NO_FREE_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_CR_PIPE_NO_FREE_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "CreatePipeErr:OS_QueueCreate failed, no free id's (app=%s)", + CFE_SB_GetAppTskName(TskId,FullName)); + break; + case CFE_SB_CR_PIPE_ERR_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_CR_PIPE_ERR_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "CreatePipeErr:OS_QueueCreate returned %d,app %s", + (int)Status,CFE_SB_GetAppTskName(TskId,FullName)); + break; + } + } - return CFE_SUCCESS; + return Status; }/* end CFE_SB_CreatePipe */ @@ -288,102 +362,143 @@ void CFE_SB_RemovePipeFromRoute(CFE_SBR_RouteId_t RouteId, void *ArgPtr) */ int32 CFE_SB_DeletePipeFull(CFE_SB_PipeId_t PipeId,CFE_ES_ResourceID_t AppId) { - uint8 PipeTblIdx; - int32 RtnFromVal; - int32 Stat; - CFE_ES_ResourceID_t Owner; + CFE_SB_PipeD_t *PipeDscPtr; + int32 Status; CFE_ES_ResourceID_t TskId; - CFE_SB_Buffer_t *BufPtr; + CFE_SB_BufferD_t *BufDscPtr; + osal_id_t SysQueueId; char FullName[(OS_MAX_API_NAME * 2)]; + size_t BufDscSize; CFE_SB_RemovePipeCallback_t Args; + uint16 PendingEventID; - /* get TaskId and name of caller for events */ - CFE_ES_GetTaskID(&TskId); - CFE_SB_GetAppTskName(TskId, FullName); + Status = CFE_SUCCESS; + PendingEventID = 0; + SysQueueId = OS_OBJECT_ID_UNDEFINED; + BufDscPtr = NULL; /* take semaphore to prevent a task switch during this call */ CFE_SB_LockSharedData(__func__,__LINE__); - /* check input parameter */ - PipeTblIdx = CFE_SB_GetPipeIdx(PipeId); - RtnFromVal = CFE_SB_ValidatePipeId(PipeId); - if((RtnFromVal != CFE_SUCCESS)||(PipeTblIdx == CFE_SB_INVALID_PIPE)) - { - CFE_SB.HKTlmMsg.Payload.CreatePipeErrorCounter++; - CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_DEL_PIPE_ERR1_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "Pipe Delete Error:Bad Argument,PipedId %d,Requestor %s,Idx %d,Stat %d", - (int)PipeId,FullName,(int)PipeTblIdx,(int)RtnFromVal); - return CFE_SB_BAD_ARGUMENT; - }/* end if */ - - Owner = CFE_SB.PipeTbl[PipeTblIdx].AppId; - + /* check input parameter */ + PipeDscPtr = CFE_SB_LocatePipeDescByID(PipeId); + if (!CFE_SB_PipeDescIsMatch(PipeDscPtr, PipeId)) + { + PendingEventID = CFE_SB_DEL_PIPE_ERR1_EID; + Status = CFE_SB_BAD_ARGUMENT; + } /* check that the given AppId is the owner of the pipe */ - if( !CFE_ES_ResourceID_Equal(AppId, Owner) ) + else if (!CFE_ES_ResourceID_Equal(AppId, PipeDscPtr->AppId)) { - CFE_SB.HKTlmMsg.Payload.CreatePipeErrorCounter++; - CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_DEL_PIPE_ERR2_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "Pipe Delete Error:Caller(%s) is not the owner of pipe %d", FullName, (int)PipeId); - return CFE_SB_BAD_ARGUMENT; - }/* end if */ - - /* Remove the pipe from all routes */ - Args.PipeId = PipeId; - Args.FullName = FullName; - CFE_SBR_ForEachRouteId(CFE_SB_RemovePipeFromRoute, &Args, NULL); - - if (CFE_SB.PipeTbl[PipeTblIdx].ToTrashBuff != NULL) { - - /* Decrement the Buffer Use Count and Free buffer if cnt=0) */ - CFE_SB_DecrBufUseCnt(CFE_SB.PipeTbl[PipeTblIdx].ToTrashBuff); - CFE_SB.PipeTbl[PipeTblIdx].ToTrashBuff = NULL; + PendingEventID = CFE_SB_DEL_PIPE_ERR2_EID; + Status = CFE_SB_BAD_ARGUMENT; + } + else + { + /* Remove the pipe from all routes */ + Args.PipeId = PipeId; + Args.FullName = FullName; + CFE_SBR_ForEachRouteId(CFE_SB_RemovePipeFromRoute, &Args, NULL); + + /* + * With the route removed there should be no new messages written to this pipe, + * + * but the pipe ID itself also needs to be invalidated now (before releasing lock) to make + * sure that no no subscriptions/routes can be added either. + * + * However we must first save certain state data for later deletion. + */ + SysQueueId = PipeDscPtr->SysQueueId; + BufDscPtr = PipeDscPtr->LastBuffer; + + /* + * Mark entry as "reserved" so other resources can be deleted + * while the SB global is unlocked. This prevents other tasks + * from trying to use this Pipe Desc slot, and also should prevents + * any task from re-subscribing to this pipe. + */ + CFE_SB_PipeDescSetUsed(PipeDscPtr, CFE_ES_RESOURCEID_RESERVED); + } - }/* end if */ + CFE_SB_UnlockSharedData(__func__,__LINE__); /* remove any messages that might be on the pipe */ - /* this step will free the memory used to store the message */ - do{ - CFE_SB_UnlockSharedData(__func__,__LINE__); - Stat = CFE_SB_ReceiveBuffer(&BufPtr,PipeId,CFE_SB_POLL); - CFE_SB_LockSharedData(__func__,__LINE__); - }while(Stat == CFE_SUCCESS); + if (Status == CFE_SUCCESS) + { + while(true) + { + /* decrement refcount of any previous buffer */ + if (BufDscPtr != NULL) + { + CFE_SB_LockSharedData(__func__,__LINE__); + CFE_SB_DecrBufUseCnt(BufDscPtr); + CFE_SB_UnlockSharedData(__func__,__LINE__); + BufDscPtr = NULL; + } - /* Delete the underlying OS queue */ - OS_QueueDelete(CFE_SB.PipeTbl[PipeTblIdx].SysQueueId); + if (OS_QueueGet(SysQueueId, &BufDscPtr, sizeof(BufDscPtr), &BufDscSize, OS_CHECK) != OS_SUCCESS) + { + /* no more messages */ + break; + } + } - /* remove the pipe from the pipe table */ - CFE_SB.PipeTbl[PipeTblIdx].InUse = CFE_SB_NOT_IN_USE; - CFE_SB.PipeTbl[PipeTblIdx].SysQueueId = CFE_SB_UNUSED_QUEUE; - CFE_SB.PipeTbl[PipeTblIdx].PipeId = CFE_SB_INVALID_PIPE; - CFE_SB.PipeTbl[PipeTblIdx].CurrentBuff = NULL; + /* Delete the underlying OS queue */ + OS_QueueDelete(SysQueueId); + } - /* zero out the pipe depth stats */ - if (PipeTblIdx < CFE_SB_TLM_PIPEDEPTHSTATS_SIZE) + /* + * Final cleanup with global data locked + */ + CFE_SB_LockSharedData(__func__,__LINE__); + + if (Status == CFE_SUCCESS) { - CFE_SB.StatTlmMsg.Payload.PipeDepthStats[PipeTblIdx].PipeId = 0; - CFE_SB.StatTlmMsg.Payload.PipeDepthStats[PipeTblIdx].Depth = 0; - CFE_SB.StatTlmMsg.Payload.PipeDepthStats[PipeTblIdx].InUse = 0; - CFE_SB.StatTlmMsg.Payload.PipeDepthStats[PipeTblIdx].PeakInUse = 0; + CFE_SB_PipeDescSetFree(PipeDscPtr); + --CFE_SB.StatTlmMsg.Payload.PipesInUse; + } + else if (PendingEventID != 0) + { + CFE_SB.HKTlmMsg.Payload.CreatePipeErrorCounter++; } - - CFE_SB.StatTlmMsg.Payload.PipesInUse--; CFE_SB_UnlockSharedData(__func__,__LINE__); - /* - * Get the app name of the actual pipe owner for the event string - * as this may be different than the task doing the deletion. - * - * Note: If this fails (e.g. bad AppID, it returns an empty string - */ - CFE_ES_GetAppName(FullName, Owner, sizeof(FullName)); + if (Status == CFE_SUCCESS) + { + /* + * Get the app name of the actual pipe owner for the event string + * as this may be different than the task doing the deletion. + * + * Note: If this fails (e.g. bad AppID, it returns an empty string + */ + CFE_ES_GetAppName(FullName, AppId, sizeof(FullName)); + + CFE_EVS_SendEventWithAppID(CFE_SB_PIPE_DELETED_EID,CFE_EVS_EventType_DEBUG,CFE_SB.AppId, + "Pipe Deleted:id %d,owner %s",(int)CFE_ES_ResourceID_ToInteger(PipeId), FullName); + } + else + { + /* get TaskId and name of caller for events */ + CFE_ES_GetTaskID(&TskId); + CFE_SB_GetAppTskName(TskId, FullName); - CFE_EVS_SendEventWithAppID(CFE_SB_PIPE_DELETED_EID,CFE_EVS_EventType_DEBUG,CFE_SB.AppId, - "Pipe Deleted:id %d,owner %s",(int)PipeId, FullName); + switch (PendingEventID) + { + case CFE_SB_DEL_PIPE_ERR1_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_DEL_PIPE_ERR1_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "Pipe Delete Error:Bad Argument,PipedId %ld,Requestor %s", + CFE_ES_ResourceID_ToInteger(PipeId),FullName); + break; + case CFE_SB_DEL_PIPE_ERR2_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_DEL_PIPE_ERR2_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "Pipe Delete Error:Caller(%s) is not the owner of pipe %ld", + FullName, CFE_ES_ResourceID_ToInteger(PipeId)); + break; + } + } - return CFE_SUCCESS; + return Status; }/* end CFE_SB_DeletePipeFull */ @@ -393,23 +508,16 @@ int32 CFE_SB_DeletePipeFull(CFE_SB_PipeId_t PipeId,CFE_ES_ResourceID_t AppId) */ int32 CFE_SB_SetPipeOpts(CFE_SB_PipeId_t PipeId, uint8 Opts) { - uint8 PipeTblIdx = 0; - int32 RtnFromVal = 0; - CFE_ES_ResourceID_t Owner; + CFE_SB_PipeD_t *PipeDscPtr; CFE_ES_ResourceID_t AppID; CFE_ES_ResourceID_t TskId; + uint16 PendingEventID; int32 Status; char FullName[(OS_MAX_API_NAME * 2)]; - Status = CFE_ES_GetAppID(&AppID); - if(Status != CFE_SUCCESS) - { - /* shouldn't happen... */ - return Status; - } + PendingEventID = 0; - /* get TaskId of caller for events */ - Status = CFE_ES_GetTaskID(&TskId); + Status = CFE_ES_GetAppID(&AppID); if(Status != CFE_SUCCESS) { /* shouldn't happen... */ @@ -420,47 +528,61 @@ int32 CFE_SB_SetPipeOpts(CFE_SB_PipeId_t PipeId, uint8 Opts) CFE_SB_LockSharedData(__func__,__LINE__); /* check input parameter */ - PipeTblIdx = CFE_SB_GetPipeIdx(PipeId); - RtnFromVal = CFE_SB_ValidatePipeId(PipeId); - - if((RtnFromVal != CFE_SUCCESS)||(PipeTblIdx == CFE_SB_INVALID_PIPE)) + PipeDscPtr = CFE_SB_LocatePipeDescByID(PipeId); + if(!CFE_SB_PipeDescIsMatch(PipeDscPtr, PipeId)) { - CFE_SB.HKTlmMsg.Payload.PipeOptsErrorCounter++; - CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_SETPIPEOPTS_ID_ERR_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "Pipe Opts Error:Bad Argument,PipedId %d,Requestor %s,Idx %d,Stat %d", - (int)PipeId,CFE_SB_GetAppTskName(TskId,FullName),(int)PipeTblIdx,(int)RtnFromVal); - return CFE_SB_BAD_ARGUMENT; - }/* end if */ + PendingEventID = CFE_SB_SETPIPEOPTS_ID_ERR_EID; + Status = CFE_SB_BAD_ARGUMENT; + } + /* check that the caller AppId is the owner of the pipe */ + else if( !CFE_ES_ResourceID_Equal(AppID, PipeDscPtr->AppId) ) + { + PendingEventID = CFE_SB_SETPIPEOPTS_OWNER_ERR_EID; + Status = CFE_SB_BAD_ARGUMENT; + } + else + { + PipeDscPtr->Opts = Opts; + } - /* check that the given AppId is the owner of the pipe */ - Owner = CFE_SB.PipeTbl[PipeTblIdx].AppId; - if( !CFE_ES_ResourceID_Equal(AppID, Owner) ) + /* If anything went wrong, increment the error counter before unlock */ + if (Status != CFE_SUCCESS) { CFE_SB.HKTlmMsg.Payload.PipeOptsErrorCounter++; - CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_SETPIPEOPTS_OWNER_ERR_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "Pipe Opts Set Error: Caller(%s) is not the owner of pipe %d", - CFE_SB_GetAppTskName(TskId,FullName),(int)PipeId); - return CFE_SB_BAD_ARGUMENT; - }/* end if */ - - CFE_SB.PipeTbl[PipeTblIdx].Opts = Opts; + } CFE_SB_UnlockSharedData(__func__,__LINE__); - /* - * Get the app name of the actual pipe owner for the event string - * as this may be different than the task doing the deletion. - * - * Note: If this fails (e.g. bad AppID, it returns an empty string - */ - CFE_ES_GetAppName(FullName, Owner, sizeof(FullName)); + /* Send events after unlocking SB */ + if (Status == CFE_SUCCESS) + { + /* get AppID of caller for events */ + CFE_ES_GetAppName(FullName, AppID, sizeof(FullName)); - CFE_EVS_SendEventWithAppID(CFE_SB_SETPIPEOPTS_EID,CFE_EVS_EventType_DEBUG,CFE_SB.AppId, - "Pipe opts set:id %d,owner %s, opts=0x%02x",(int)PipeId, FullName, (unsigned int)Opts); + CFE_EVS_SendEventWithAppID(CFE_SB_SETPIPEOPTS_EID,CFE_EVS_EventType_DEBUG,CFE_SB.AppId, + "Pipe opts set:id %lu,owner %s, opts=0x%02x",CFE_ES_ResourceID_ToInteger(PipeId), FullName, (unsigned int)Opts); + } + else + { + /* get TaskId of caller for events */ + CFE_ES_GetTaskID(&TskId); - return CFE_SUCCESS; + switch (PendingEventID) + { + case CFE_SB_SETPIPEOPTS_ID_ERR_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_SETPIPEOPTS_ID_ERR_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "Pipe Opts Error:Bad Argument,PipedId %lu,Requestor %s", + CFE_ES_ResourceID_ToInteger(PipeId),CFE_SB_GetAppTskName(TskId,FullName)); + break; + case CFE_SB_SETPIPEOPTS_OWNER_ERR_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_SETPIPEOPTS_OWNER_ERR_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "Pipe Opts Set Error: Caller(%s) is not the owner of pipe %lu", + CFE_SB_GetAppTskName(TskId,FullName),CFE_ES_ResourceID_ToInteger(PipeId)); + break; + } + } + + return Status; }/* end CFE_SB_SetPipeOpts */ /* @@ -468,97 +590,162 @@ int32 CFE_SB_SetPipeOpts(CFE_SB_PipeId_t PipeId, uint8 Opts) */ int32 CFE_SB_GetPipeOpts(CFE_SB_PipeId_t PipeId, uint8 *OptsPtr) { - uint8 PipeTblIdx = 0; - int32 RtnFromVal = 0; + int32 Status; CFE_ES_ResourceID_t TskId; char FullName[(OS_MAX_API_NAME * 2)]; + uint16 PendingEventID; + CFE_SB_PipeD_t *PipeDscPtr; - /* get TaskId of caller for events */ - CFE_ES_GetTaskID(&TskId); - - if(OptsPtr == NULL) - { - CFE_SB.HKTlmMsg.Payload.PipeOptsErrorCounter++; - CFE_EVS_SendEventWithAppID(CFE_SB_GETPIPEOPTS_PTR_ERR_EID, CFE_EVS_EventType_ERROR, CFE_SB.AppId, - "Pipe Opts Error:Bad Argument,Requestor %s", - CFE_SB_GetAppTskName(TskId,FullName)); - return CFE_SB_BAD_ARGUMENT; - } + PendingEventID = 0; + Status = CFE_SUCCESS; /* take semaphore to prevent a task switch during this call */ CFE_SB_LockSharedData(__func__,__LINE__); /* check input parameter */ - PipeTblIdx = CFE_SB_GetPipeIdx(PipeId); - RtnFromVal = CFE_SB_ValidatePipeId(PipeId); + PipeDscPtr = CFE_SB_LocatePipeDescByID(PipeId); + if (!CFE_SB_PipeDescIsMatch(PipeDscPtr, PipeId)) + { + PendingEventID = CFE_SB_GETPIPEOPTS_ID_ERR_EID; + Status = CFE_SB_BAD_ARGUMENT; + } + else if (OptsPtr == NULL) + { + PendingEventID = CFE_SB_GETPIPEOPTS_PTR_ERR_EID; + Status = CFE_SB_BAD_ARGUMENT; + } + else + { + *OptsPtr = PipeDscPtr->Opts; + } - if((RtnFromVal != CFE_SUCCESS)||(PipeTblIdx == CFE_SB_INVALID_PIPE)) + /* If anything went wrong, increment the error counter before unlock */ + if (Status != CFE_SUCCESS) { CFE_SB.HKTlmMsg.Payload.PipeOptsErrorCounter++; - CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_GETPIPEOPTS_ID_ERR_EID, CFE_EVS_EventType_ERROR, CFE_SB.AppId, - "Pipe Opts Error:Bad Argument,PipedId %d,Requestor %s,Idx %d,Stat %d", - (int)PipeId,CFE_SB_GetAppTskName(TskId,FullName),(int)PipeTblIdx,(int)RtnFromVal); - return CFE_SB_BAD_ARGUMENT; - }/* end if */ - - *OptsPtr = CFE_SB.PipeTbl[PipeTblIdx].Opts; + } CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_GETPIPEOPTS_EID,CFE_EVS_EventType_DEBUG,CFE_SB.AppId, - "Pipe opts set:id %d, opts=0x%02x",(int)PipeId, (unsigned int)*OptsPtr); - return CFE_SUCCESS; + + /* Send events after unlocking SB */ + if (Status == CFE_SUCCESS) + { + CFE_EVS_SendEventWithAppID(CFE_SB_GETPIPEOPTS_EID,CFE_EVS_EventType_DEBUG,CFE_SB.AppId, + "Pipe opts get:id %lu, opts=0x%02x",CFE_ES_ResourceID_ToInteger(PipeId), (unsigned int)*OptsPtr); + } + else + { + /* get TaskId of caller for events */ + CFE_ES_GetTaskID(&TskId); + + switch(PendingEventID) + { + case CFE_SB_GETPIPEOPTS_PTR_ERR_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_GETPIPEOPTS_PTR_ERR_EID, CFE_EVS_EventType_ERROR, CFE_SB.AppId, + "Pipe Opts Error:Bad Argument,Requestor %s", + CFE_SB_GetAppTskName(TskId,FullName)); + break; + case CFE_SB_GETPIPEOPTS_ID_ERR_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_GETPIPEOPTS_ID_ERR_EID, CFE_EVS_EventType_ERROR, CFE_SB.AppId, + "Pipe Opts Error:Bad Argument,PipedId %lu,Requestor %s", + CFE_ES_ResourceID_ToInteger(PipeId),CFE_SB_GetAppTskName(TskId,FullName)); + break; + } + } + + return Status; }/* end CFE_SB_GetPipeOpts */ /* * Function: CFE_SB_GetPipeName - See API and header file for details */ -int32 CFE_SB_GetPipeName(char *PipeNameBuf, size_t PipeNameSize, CFE_SB_PipeId_t PipeId){ - OS_queue_prop_t queue_prop; - int32 Status = CFE_SUCCESS; - CFE_ES_ResourceID_t TskId; - char FullName[(OS_MAX_API_NAME * 2)]; +int32 CFE_SB_GetPipeName(char *PipeNameBuf, size_t PipeNameSize, CFE_SB_PipeId_t PipeId) +{ + int32 Status; + CFE_ES_ResourceID_t TskId; + char FullName[(OS_MAX_API_NAME * 2)]; + uint16 PendingEventID; + CFE_SB_PipeD_t *PipeDscPtr; + osal_id_t SysQueueId; - if(PipeNameBuf == NULL || PipeNameSize == 0) { - CFE_ES_GetTaskID(&TskId); - CFE_EVS_SendEventWithAppID(CFE_SB_GETPIPENAME_NULL_PTR_EID, CFE_EVS_EventType_ERROR, - CFE_SB.AppId, "Pipe Name Error:NullPtr,Requestor %s", - CFE_SB_GetAppTskName(TskId,FullName)); + PendingEventID = 0; + Status = CFE_SUCCESS; + SysQueueId = OS_OBJECT_ID_UNDEFINED; + + /* take semaphore to prevent a task switch during this call */ + CFE_SB_LockSharedData(__func__,__LINE__); + /* check input parameter */ + PipeDscPtr = CFE_SB_LocatePipeDescByID(PipeId); + if (!CFE_SB_PipeDescIsMatch(PipeDscPtr, PipeId)) + { + PendingEventID = CFE_SB_GETPIPENAME_ID_ERR_EID; Status = CFE_SB_BAD_ARGUMENT; - } else if(PipeId >= CFE_PLATFORM_SB_MAX_PIPES){ - CFE_ES_GetTaskID(&TskId); - CFE_EVS_SendEventWithAppID(CFE_SB_GETPIPENAME_ID_ERR_EID, CFE_EVS_EventType_ERROR, - CFE_SB.AppId, "Pipe Id Error:Bad Argument,Id=%d,Requestor %s", - PipeId,CFE_SB_GetAppTskName(TskId,FullName)); + } + else + { + SysQueueId = PipeDscPtr->SysQueueId; + } - memset(PipeNameBuf, 0, PipeNameSize); + CFE_SB_UnlockSharedData(__func__,__LINE__); - Status = CFE_SB_BAD_ARGUMENT; - }else{ - if (OS_QueueGetInfo(CFE_SB.PipeTbl[PipeId].SysQueueId, &queue_prop) - == OS_SUCCESS){ - strncpy(PipeNameBuf, queue_prop.name, PipeNameSize-1); + if (Status == CFE_SUCCESS) + { + if (PipeNameBuf == NULL || PipeNameSize == 0) + { + PendingEventID = CFE_SB_GETPIPENAME_NULL_PTR_EID; + Status = CFE_SB_BAD_ARGUMENT; + } + else + { + Status = OS_GetResourceName(SysQueueId, PipeNameBuf, PipeNameSize); - PipeNameBuf[PipeNameSize-1] = '\0'; + if (Status == OS_SUCCESS) + { + Status = CFE_SUCCESS; + } + else + { + PendingEventID = CFE_SB_GETPIPENAME_ID_ERR_EID; + Status = CFE_SB_BAD_ARGUMENT; + } + } + } - CFE_EVS_SendEventWithAppID(CFE_SB_GETPIPENAME_EID, + /* Send Events */ + if (Status == CFE_SUCCESS) + { + CFE_EVS_SendEventWithAppID(CFE_SB_GETPIPENAME_EID, CFE_EVS_EventType_DEBUG,CFE_SB.AppId, - "GetPipeName name=%s id=%d", - PipeNameBuf, PipeId); - } else{ - CFE_ES_GetTaskID(&TskId); - CFE_EVS_SendEventWithAppID(CFE_SB_GETPIPENAME_ID_ERR_EID, CFE_EVS_EventType_ERROR, - CFE_SB.AppId, "Pipe Id Error:Bad Argument,Id=%d,Requestor %s", - PipeId,CFE_SB_GetAppTskName(TskId,FullName)); + "GetPipeName name=%s id=%lu", + PipeNameBuf, CFE_ES_ResourceID_ToInteger(PipeId)); + } + else + { + CFE_ES_GetTaskID(&TskId); - memset(PipeNameBuf, 0, PipeNameSize); + switch(PendingEventID) + { + case CFE_SB_GETPIPENAME_NULL_PTR_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_GETPIPENAME_NULL_PTR_EID, CFE_EVS_EventType_ERROR, + CFE_SB.AppId, "Pipe Name Error:NullPtr,Requestor %s", + CFE_SB_GetAppTskName(TskId,FullName)); + break; + case CFE_SB_GETPIPENAME_ID_ERR_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_GETPIPENAME_ID_ERR_EID, CFE_EVS_EventType_ERROR, + CFE_SB.AppId, "Pipe Id Error:Bad Argument,Id=%lu,Requestor %s", + CFE_ES_ResourceID_ToInteger(PipeId),CFE_SB_GetAppTskName(TskId,FullName)); + break; + } - Status = CFE_SB_BAD_ARGUMENT; - }/* end if */ - }/* end if */ + if (PipeNameBuf != NULL && PipeNameSize > 0) + { + memset(PipeNameBuf, 0, PipeNameSize); + } + } return Status; + }/* end CFE_SB_GetPipeName */ /* @@ -566,89 +753,103 @@ int32 CFE_SB_GetPipeName(char *PipeNameBuf, size_t PipeNameSize, CFE_SB_PipeId_t */ int32 CFE_SB_GetPipeIdByName(CFE_SB_PipeId_t *PipeIdPtr, const char *PipeName) { - uint8 PipeTblIdx = 0; - int32 Status = CFE_SUCCESS; - int32 RtnFromVal = 0; + int32 Status; CFE_ES_ResourceID_t TskId; - osal_id_t QueueId; + uint32 Idx; char FullName[(OS_MAX_API_NAME * 2)]; + uint16 PendingEventID; + CFE_SB_PipeD_t *PipeDscPtr; + osal_id_t SysQueueId; - /* get TaskId of caller for events */ - CFE_ES_GetTaskID(&TskId); + PendingEventID = 0; + Status = CFE_SUCCESS; + SysQueueId = OS_OBJECT_ID_UNDEFINED; if(PipeName == NULL || PipeIdPtr == NULL) { - CFE_SB.HKTlmMsg.Payload.GetPipeIdByNameErrorCounter++; - - CFE_EVS_SendEventWithAppID(CFE_SB_GETPIPEIDBYNAME_NULL_ERR_EID, CFE_EVS_EventType_ERROR, CFE_SB.AppId, - "Pipe ID By Name Error:Bad Argument,Requestor %s", - CFE_SB_GetAppTskName(TskId,FullName)); - + PendingEventID = CFE_SB_GETPIPEIDBYNAME_NULL_ERR_EID; Status = CFE_SB_BAD_ARGUMENT; } else { - RtnFromVal = OS_QueueGetIdByName(&QueueId, PipeName); - - if(RtnFromVal == OS_SUCCESS) + /* Get QueueID from OSAL */ + Status = OS_QueueGetIdByName(&SysQueueId, PipeName); + if (Status == OS_SUCCESS) { - /* take semaphore to prevent a task switch while iterating - * through the PipeTbl. - */ - CFE_SB_LockSharedData(__func__,__LINE__); + Status = CFE_SUCCESS; + } + else + { + PendingEventID = CFE_SB_GETPIPEIDBYNAME_NAME_ERR_EID; + Status = CFE_SB_BAD_ARGUMENT; + } + } + + CFE_SB_LockSharedData(__func__,__LINE__); - for(PipeTblIdx = 0; - PipeTblIdx < CFE_PLATFORM_SB_MAX_PIPES; - PipeTblIdx++) + if (Status == CFE_SUCCESS) + { + Idx = CFE_PLATFORM_SB_MAX_PIPES; + PipeDscPtr = CFE_SB.PipeTbl; + while(true) + { + if (Idx == 0) { - if(CFE_SB.PipeTbl[PipeTblIdx].InUse != 0 - && OS_ObjectIdEqual(CFE_SB.PipeTbl[PipeTblIdx].SysQueueId, QueueId)) - { - /* grab the ID before we release the lock */ - *PipeIdPtr = CFE_SB.PipeTbl[PipeTblIdx].PipeId; + PendingEventID = CFE_SB_GETPIPEIDBYNAME_NAME_ERR_EID; + Status = CFE_SB_BAD_ARGUMENT; + break; + } - break; - }/* end if */ + if (OS_ObjectIdEqual(PipeDscPtr->SysQueueId, SysQueueId)) + { + /* grab the ID before we release the lock */ + *PipeIdPtr = CFE_SB_PipeDescGetID(PipeDscPtr); + break; + }/* end if */ - }/* end for */ + --Idx; + ++PipeDscPtr; + } + } + + if (Status != CFE_SUCCESS) + { + ++CFE_SB.HKTlmMsg.Payload.GetPipeIdByNameErrorCounter; + } - CFE_SB_UnlockSharedData(__func__,__LINE__); + CFE_SB_UnlockSharedData(__func__,__LINE__); - if(PipeTblIdx == CFE_PLATFORM_SB_MAX_PIPES) - { - /* should never get here! */ - CFE_SB.HKTlmMsg.Payload.GetPipeIdByNameErrorCounter++; + /* Send Events */ + if (Status == CFE_SUCCESS) + { + CFE_EVS_SendEventWithAppID(CFE_SB_GETPIPEIDBYNAME_EID, + CFE_EVS_EventType_DEBUG,CFE_SB.AppId, + "PipeIdByName name=%s id=%lu", + PipeName, CFE_ES_ResourceID_ToInteger(*PipeIdPtr)); + } + else + { + /* get TaskId of caller for events */ + CFE_ES_GetTaskID(&TskId); + + switch(PendingEventID) + { + case CFE_SB_GETPIPEIDBYNAME_NULL_ERR_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_GETPIPEIDBYNAME_NULL_ERR_EID, + CFE_EVS_EventType_ERROR, CFE_SB.AppId, + "Pipe ID By Name Error:Bad Argument,Requestor %s", + CFE_SB_GetAppTskName(TskId,FullName)); + break; + case CFE_SB_GETPIPEIDBYNAME_NAME_ERR_EID: CFE_EVS_SendEventWithAppID(CFE_SB_GETPIPEIDBYNAME_NAME_ERR_EID, CFE_EVS_EventType_ERROR, CFE_SB.AppId, "Pipe ID By Name Error:Bad Argument,Requestor %s", CFE_SB_GetAppTskName(TskId,FullName)); + break; - Status = CFE_SB_BAD_ARGUMENT; - } - else - { - CFE_EVS_SendEventWithAppID(CFE_SB_GETPIPEIDBYNAME_EID, - CFE_EVS_EventType_DEBUG,CFE_SB.AppId, - "PipeIdByName name=%s id=%d", - PipeName, *PipeIdPtr); - - Status = CFE_SUCCESS; - } } - else - { - CFE_SB.HKTlmMsg.Payload.GetPipeIdByNameErrorCounter++; - - CFE_EVS_SendEventWithAppID(CFE_SB_GETPIPEIDBYNAME_NAME_ERR_EID, - CFE_EVS_EventType_ERROR, CFE_SB.AppId, - "Pipe ID By Name Error:Bad Argument,Requestor %s", - CFE_SB_GetAppTskName(TskId,FullName)); - - Status = CFE_SB_BAD_ARGUMENT; - }/* end if */ - - }/* end if */ + } return Status; @@ -731,17 +932,21 @@ int32 CFE_SB_SubscribeFull(CFE_SB_MsgId_t MsgId, uint8 Scope) { CFE_SBR_RouteId_t RouteId; - int32 Stat; - CFE_ES_ResourceID_t TskId; + CFE_SB_PipeD_t *PipeDscPtr; + int32 Status; + CFE_ES_ResourceID_t TskId; CFE_ES_ResourceID_t AppId; - uint8 PipeIdx; - CFE_SB_DestinationD_t *DestPtr = NULL; - uint32 DestCount = 0; + CFE_SB_DestinationD_t *DestPtr; + uint32 DestCount; char FullName[(OS_MAX_API_NAME * 2)]; - char PipeName[OS_MAX_API_NAME] = {'\0'}; - uint32 Collisions = 0; + char PipeName[OS_MAX_API_NAME]; + uint32 Collisions; + uint16 PendingEventID; - CFE_SB_GetPipeName(PipeName, sizeof(PipeName), PipeId); + PendingEventID = 0; + Status = CFE_SUCCESS; + DestPtr = NULL; + Collisions = 0; /* get the callers Application Id */ CFE_ES_GetAppID(&AppId); @@ -753,153 +958,208 @@ int32 CFE_SB_SubscribeFull(CFE_SB_MsgId_t MsgId, CFE_SB_LockSharedData(__func__,__LINE__); /* check that the pipe has been created */ - PipeIdx = CFE_SB_GetPipeIdx(PipeId); - if(PipeIdx==CFE_SB_INVALID_PIPE){ - CFE_SB.HKTlmMsg.Payload.SubscribeErrorCounter++; - CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_SUB_INV_PIPE_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "Subscribe Err:Invalid Pipe Id,Msg=0x%x,PipeId=%d,App %s",(unsigned int)CFE_SB_MsgIdToValue(MsgId), - (int)PipeId, CFE_SB_GetAppTskName(TskId,FullName)); - return CFE_SB_BAD_ARGUMENT; - }/* end if */ - - /* check that the requestor is the owner of the pipe */ - if( !CFE_ES_ResourceID_Equal(CFE_SB.PipeTbl[PipeIdx].AppId, AppId)){ - CFE_SB.HKTlmMsg.Payload.SubscribeErrorCounter++; - CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_SUB_INV_CALLER_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "Subscribe Err:Caller(%s) is not the owner of pipe %d,Msg=0x%x", - CFE_SB_GetAppTskName(TskId,FullName),(int)PipeId,(unsigned int)CFE_SB_MsgIdToValue(MsgId)); - return CFE_SB_BAD_ARGUMENT; - }/* end if */ - + PipeDscPtr = CFE_SB_LocatePipeDescByID(PipeId); + if (!CFE_SB_PipeDescIsMatch(PipeDscPtr, PipeId)) + { + PendingEventID = CFE_SB_SUB_INV_PIPE_EID; + Status = CFE_SB_BAD_ARGUMENT; + } + else if (!CFE_ES_ResourceID_Equal(PipeDscPtr->AppId, AppId)) + { + PendingEventID = CFE_SB_SUB_INV_CALLER_EID; + Status = CFE_SB_BAD_ARGUMENT; + } /* check message id key and scope */ - if(!CFE_SB_IsValidMsgId(MsgId) || (Scope > 1)) + else if (!CFE_SB_IsValidMsgId(MsgId) || (Scope > 1)) { - CFE_SB.HKTlmMsg.Payload.SubscribeErrorCounter++; - CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_SUB_ARG_ERR_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "Subscribe Err:Bad Arg,MsgId 0x%x,PipeId %d,app %s,scope %d", - (unsigned int)CFE_SB_MsgIdToValue(MsgId), - (int)PipeId,CFE_SB_GetAppTskName(TskId,FullName),Scope); - return CFE_SB_BAD_ARGUMENT; - }/* end if */ - - RouteId = CFE_SBR_GetRouteId(MsgId); - if (CFE_SBR_IsValidRouteId(RouteId)) + PendingEventID = CFE_SB_SUB_ARG_ERR_EID; + Status = CFE_SB_BAD_ARGUMENT; + } + else { - /* check for duplicate subscription */ - if(CFE_SB_GetDestPtr(RouteId, PipeId) != NULL) + /* Get the route, adding one if it does not exist already */ + RouteId = CFE_SBR_GetRouteId(MsgId); + + if (!CFE_SBR_IsValidRouteId(RouteId)) { - CFE_SB.HKTlmMsg.Payload.DuplicateSubscriptionsCounter++; - CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_DUP_SUBSCRIP_EID,CFE_EVS_EventType_INFORMATION,CFE_SB.AppId, - "Duplicate Subscription,MsgId 0x%x on %s pipe,app %s", - (unsigned int)CFE_SB_MsgIdToValue(MsgId), - PipeName,CFE_SB_GetAppTskName(TskId,FullName)); - return CFE_SUCCESS; + /* Add the route */ + RouteId = CFE_SBR_AddRoute(MsgId, &Collisions); + + /* if all routing table elements are used, send event */ + if (!CFE_SBR_IsValidRouteId(RouteId)) + { + PendingEventID = CFE_SB_MAX_MSGS_MET_EID; + Status = CFE_SB_MAX_MSGS_MET; + } + else + { + /* Increment the MsgIds in use ctr and if it's > the high water mark,*/ + /* adjust the high water mark */ + CFE_SB.StatTlmMsg.Payload.MsgIdsInUse++; + if(CFE_SB.StatTlmMsg.Payload.MsgIdsInUse > CFE_SB.StatTlmMsg.Payload.PeakMsgIdsInUse) + { + CFE_SB.StatTlmMsg.Payload.PeakMsgIdsInUse = CFE_SB.StatTlmMsg.Payload.MsgIdsInUse; + }/* end if */ + } } + } - /* Check for destination limit */ - for (DestPtr = CFE_SBR_GetDestListHeadPtr(RouteId); DestPtr != NULL; DestPtr = DestPtr->Next) + /* If successful up to this point, check if new dest should be added to this route */ + if (Status == CFE_SUCCESS) + { + DestCount = 0; + for (DestPtr = CFE_SBR_GetDestListHeadPtr(RouteId); + DestPtr != NULL; + DestPtr = DestPtr->Next) { - DestCount++; + ++DestCount; + + /* Check if duplicate (status stays as CFE_SUCCESS) */ + if (CFE_ES_ResourceID_Equal(DestPtr->PipeId, PipeId)) + { + PendingEventID = CFE_SB_DUP_SUBSCRIP_EID; + break; + } + + /* Check if limit reached */ + if (DestCount >= CFE_PLATFORM_SB_MAX_DEST_PER_PKT) + { + PendingEventID = CFE_SB_MAX_DESTS_MET_EID; + Status = CFE_SB_MAX_DESTS_MET; + break; + } + } - if(DestCount >= CFE_PLATFORM_SB_MAX_DEST_PER_PKT){ - CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_MAX_DESTS_MET_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "Subscribe Err:Max Dests(%d)In Use For Msg 0x%x,pipe %s,app %s", - CFE_PLATFORM_SB_MAX_DEST_PER_PKT, - (unsigned int)CFE_SB_MsgIdToValue(MsgId), - PipeName, CFE_SB_GetAppTskName(TskId,FullName)); - return CFE_SB_MAX_DESTS_MET; + /* If no existing dest found, add one now */ + if (DestPtr == NULL) + { + DestPtr = CFE_SB_GetDestinationBlk(); + if(DestPtr == NULL) + { + PendingEventID = CFE_SB_DEST_BLK_ERR_EID; + Status = CFE_SB_BUF_ALOC_ERR; + } + else + { + /* initialize destination block */ + DestPtr->PipeId = PipeId; + DestPtr->MsgId2PipeLim = MsgLim; + DestPtr->Active = CFE_SB_ACTIVE; + DestPtr->BuffCount = 0; + DestPtr->DestCnt = 0; + DestPtr->Scope = Scope; + DestPtr->Prev = NULL; + DestPtr->Next = NULL; + + /* add destination node */ + CFE_SB_AddDestNode(RouteId, DestPtr); + + CFE_SB.StatTlmMsg.Payload.SubscriptionsInUse++; + if(CFE_SB.StatTlmMsg.Payload.SubscriptionsInUse > CFE_SB.StatTlmMsg.Payload.PeakSubscriptionsInUse) + { + CFE_SB.StatTlmMsg.Payload.PeakSubscriptionsInUse = CFE_SB.StatTlmMsg.Payload.SubscriptionsInUse; + } + } } } - else + + /* Increment counter before unlock */ + switch(PendingEventID) { - /* Add the route */ - RouteId = CFE_SBR_AddRoute(MsgId, &Collisions); + case CFE_SB_SUB_INV_PIPE_EID: + case CFE_SB_SUB_INV_CALLER_EID: + case CFE_SB_SUB_ARG_ERR_EID: + case CFE_SB_MAX_MSGS_MET_EID: + case CFE_SB_DEST_BLK_ERR_EID: + case CFE_SB_MAX_DESTS_MET_EID: + CFE_SB.HKTlmMsg.Payload.SubscribeErrorCounter++; + break; + case CFE_SB_DUP_SUBSCRIP_EID: + CFE_SB.HKTlmMsg.Payload.DuplicateSubscriptionsCounter++; + break; + } - /* if all routing table elements are used, send event */ - if(!CFE_SBR_IsValidRouteId(RouteId)){ - CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_MAX_MSGS_MET_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "Subscribe Err:Max Msgs(%d)In Use,MsgId 0x%x,pipe %s,app %s", - CFE_PLATFORM_SB_MAX_MSG_IDS, - (unsigned int)CFE_SB_MsgIdToValue(MsgId), - PipeName,CFE_SB_GetAppTskName(TskId,FullName)); - return CFE_SB_MAX_MSGS_MET; - }/* end if */ + CFE_SB_UnlockSharedData(__func__,__LINE__); - /* Increment the MsgIds in use ctr and if it's > the high water mark,*/ - /* adjust the high water mark */ - CFE_SB.StatTlmMsg.Payload.MsgIdsInUse++; - if(CFE_SB.StatTlmMsg.Payload.MsgIdsInUse > CFE_SB.StatTlmMsg.Payload.PeakMsgIdsInUse){ - CFE_SB.StatTlmMsg.Payload.PeakMsgIdsInUse = CFE_SB.StatTlmMsg.Payload.MsgIdsInUse; - }/* end if */ + /* Send events now */ + if (PendingEventID != 0) + { + CFE_SB_GetPipeName(PipeName, sizeof(PipeName), PipeId); - }/* end if */ + switch(PendingEventID) + { + case CFE_SB_DUP_SUBSCRIP_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_DUP_SUBSCRIP_EID,CFE_EVS_EventType_INFORMATION,CFE_SB.AppId, + "Duplicate Subscription,MsgId 0x%x on %s pipe,app %s", + (unsigned int)CFE_SB_MsgIdToValue(MsgId), + PipeName,CFE_SB_GetAppTskName(TskId,FullName)); + break; + + case CFE_SB_SUB_INV_CALLER_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_SUB_INV_CALLER_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "Subscribe Err:Caller(%s) is not the owner of pipe %lu,Msg=0x%x", + CFE_SB_GetAppTskName(TskId,FullName),CFE_ES_ResourceID_ToInteger(PipeId), + (unsigned int)CFE_SB_MsgIdToValue(MsgId)); + break; + + case CFE_SB_SUB_INV_PIPE_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_SUB_INV_PIPE_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "Subscribe Err:Invalid Pipe Id,Msg=0x%x,PipeId=%lu,App %s", + (unsigned int)CFE_SB_MsgIdToValue(MsgId), + CFE_ES_ResourceID_ToInteger(PipeId), CFE_SB_GetAppTskName(TskId,FullName)); + break; - DestPtr = CFE_SB_GetDestinationBlk(); - if(DestPtr == NULL){ - CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_DEST_BLK_ERR_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "Subscribe Err:Request for Destination Blk failed for Msg 0x%x", - (unsigned int)CFE_SB_MsgIdToValue(MsgId)); - return CFE_SB_BUF_ALOC_ERR; - }/* end if */ + case CFE_SB_DEST_BLK_ERR_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_DEST_BLK_ERR_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "Subscribe Err:Request for Destination Blk failed for Msg 0x%x", + (unsigned int)CFE_SB_MsgIdToValue(MsgId)); + break; - /* initialize destination block */ - DestPtr->PipeId = PipeId; - DestPtr->MsgId2PipeLim = (uint16)MsgLim; - DestPtr->Active = CFE_SB_ACTIVE; - DestPtr->BuffCount = 0; - DestPtr->DestCnt = 0; - DestPtr->Scope = Scope; - DestPtr->Prev = NULL; - DestPtr->Next = NULL; + case CFE_SB_MAX_DESTS_MET_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_MAX_DESTS_MET_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "Subscribe Err:Max Dests(%d)In Use For Msg 0x%x,pipe %s,app %s", + CFE_PLATFORM_SB_MAX_DEST_PER_PKT, (unsigned int)CFE_SB_MsgIdToValue(MsgId), + PipeName, CFE_SB_GetAppTskName(TskId,FullName)); + break; - /* add destination node */ - CFE_SB_AddDestNode(RouteId, DestPtr); + case CFE_SB_MAX_MSGS_MET_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_MAX_MSGS_MET_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "Subscribe Err:Max Msgs(%d)In Use,MsgId 0x%x,pipe %s,app %s", + CFE_PLATFORM_SB_MAX_MSG_IDS, (unsigned int)CFE_SB_MsgIdToValue(MsgId), + PipeName, CFE_SB_GetAppTskName(TskId,FullName)); + break; - CFE_SB.StatTlmMsg.Payload.SubscriptionsInUse++; - if(CFE_SB.StatTlmMsg.Payload.SubscriptionsInUse > CFE_SB.StatTlmMsg.Payload.PeakSubscriptionsInUse) + case CFE_SB_SUB_ARG_ERR_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_SUB_ARG_ERR_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "Subscribe Err:Bad Arg,MsgId 0x%x,PipeId %lu,app %s,scope %d", + (unsigned int)CFE_SB_MsgIdToValue(MsgId), + CFE_ES_ResourceID_ToInteger(PipeId),CFE_SB_GetAppTskName(TskId,FullName),Scope); + break; + } + } + else if (Status == CFE_SUCCESS) { - CFE_SB.StatTlmMsg.Payload.PeakSubscriptionsInUse = CFE_SB.StatTlmMsg.Payload.SubscriptionsInUse; - }/* end if */ - - if((CFE_SB.SubscriptionReporting == CFE_SB_ENABLE)&&(Scope==CFE_SB_GLOBAL)){ - CFE_SB.SubRprtMsg.Payload.MsgId = MsgId; - CFE_SB.SubRprtMsg.Payload.Pipe = PipeId; - CFE_SB.SubRprtMsg.Payload.Qos.Priority = Quality.Priority; - CFE_SB.SubRprtMsg.Payload.Qos.Reliability = Quality.Reliability; - CFE_SB.SubRprtMsg.Payload.SubType = CFE_SB_SUBSCRIPTION; - CFE_SB_UnlockSharedData(__func__,__LINE__); - Stat = CFE_SB_TransmitMsg(&CFE_SB.SubRprtMsg.Hdr.Msg, true); - CFE_EVS_SendEventWithAppID(CFE_SB_SUBSCRIPTION_RPT_EID,CFE_EVS_EventType_DEBUG,CFE_SB.AppId, - "Sending Subscription Report Msg=0x%x,Pipe=%d,Stat=0x%x", + /* If no other event pending, send a debug event indicating success */ + CFE_EVS_SendEventWithAppID(CFE_SB_SUBSCRIPTION_RCVD_EID,CFE_EVS_EventType_DEBUG,CFE_SB.AppId, + "Subscription Rcvd:MsgId 0x%x on %s(%lu),app %s", (unsigned int)CFE_SB_MsgIdToValue(MsgId), - (int)PipeId,(unsigned int)Stat); - CFE_SB_LockSharedData(__func__,__LINE__);/* to prevent back-to-back unlock */ - }/* end if */ - - /* release the semaphore */ - CFE_SB_UnlockSharedData(__func__,__LINE__); + PipeName,CFE_ES_ResourceID_ToInteger(PipeId),CFE_SB_GetAppTskName(TskId,FullName)); + } - CFE_EVS_SendEventWithAppID(CFE_SB_SUBSCRIPTION_RCVD_EID,CFE_EVS_EventType_DEBUG,CFE_SB.AppId, - "Subscription Rcvd:MsgId 0x%x on %s(%d),app %s", - (unsigned int)CFE_SB_MsgIdToValue(MsgId), - PipeName,(int)PipeId,CFE_SB_GetAppTskName(TskId,FullName)); + if (Status == CFE_SUCCESS && Scope == CFE_SB_GLOBAL) + { + CFE_SB_SendSubscriptionReport(MsgId, PipeId, Quality); + } if (Collisions != 0) { CFE_EVS_SendEventWithAppID(CFE_SB_HASHCOLLISION_EID, CFE_EVS_EventType_DEBUG, CFE_SB.AppId, - "Msg hash collision: MsgId = 0x%x, collisions = %u", - (unsigned int)CFE_SB_MsgIdToValue(MsgId), (unsigned int)Collisions); + "Msg hash collision: MsgId = 0x%x, collisions = %u", + (unsigned int)CFE_SB_MsgIdToValue(MsgId), (unsigned int)Collisions); } - return CFE_SUCCESS; + return Status; }/* end CFE_SB_SubscribeFull */ @@ -1006,12 +1266,18 @@ int32 CFE_SB_UnsubscribeWithAppId(CFE_SB_MsgId_t MsgId, int32 CFE_SB_UnsubscribeFull(CFE_SB_MsgId_t MsgId,CFE_SB_PipeId_t PipeId, uint8 Scope,CFE_ES_ResourceID_t AppId) { + int32 Status; CFE_SBR_RouteId_t RouteId; - uint32 PipeIdx; CFE_ES_ResourceID_t TskId; - CFE_SB_DestinationD_t *DestPtr = NULL; + CFE_SB_DestinationD_t *DestPtr; char FullName[(OS_MAX_API_NAME * 2)]; - char PipeName[OS_MAX_API_NAME] = {'\0'}; + char PipeName[OS_MAX_API_NAME]; + CFE_SB_PipeD_t *PipeDscPtr; + uint16 PendingEventID; + + PendingEventID = 0; + Status = CFE_SUCCESS; + DestPtr = NULL; /* get TaskId of caller for events */ CFE_ES_GetTaskID(&TskId); @@ -1020,83 +1286,98 @@ int32 CFE_SB_UnsubscribeFull(CFE_SB_MsgId_t MsgId,CFE_SB_PipeId_t PipeId, CFE_SB_LockSharedData(__func__,__LINE__); /* check that the pipe has been created */ - PipeIdx = CFE_SB_GetPipeIdx(PipeId); - if(PipeIdx==CFE_SB_INVALID_PIPE){ - CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_UNSUB_INV_PIPE_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "Unsubscribe Err:Invalid Pipe Id Msg=0x%x,Pipe=%d,app=%s", - (unsigned int)CFE_SB_MsgIdToValue(MsgId), - (int)PipeId,CFE_SB_GetAppTskName(TskId,FullName)); - return CFE_SB_BAD_ARGUMENT; - }/* end if */ - + PipeDscPtr = CFE_SB_LocatePipeDescByID(PipeId); + if (!CFE_SB_PipeDescIsMatch(PipeDscPtr, PipeId)) + { + PendingEventID = CFE_SB_UNSUB_INV_PIPE_EID; + Status = CFE_SB_BAD_ARGUMENT; + } /* if given 'AppId' is not the owner of the pipe, send error event and return */ - if( !CFE_ES_ResourceID_Equal(CFE_SB.PipeTbl[PipeIdx].AppId, AppId) ) - { - CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_UNSUB_INV_CALLER_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "Unsubscribe Err:Caller(%s) is not the owner of pipe %d,Msg=0x%x", - CFE_SB_GetAppTskName(TskId,FullName),(int)PipeId, - (unsigned int)CFE_SB_MsgIdToValue(MsgId)); - return CFE_SB_BAD_ARGUMENT; - }/* end if */ - + else if (!CFE_ES_ResourceID_Equal(PipeDscPtr->AppId, AppId)) + { + PendingEventID = CFE_SB_UNSUB_INV_CALLER_EID; + Status = CFE_SB_BAD_ARGUMENT; + } /* check input parameters */ - if(!CFE_SB_IsValidMsgId(MsgId) || - (CFE_SB_ValidatePipeId(PipeId) != CFE_SUCCESS)|| - (Scope > 1)) + else if (!CFE_SB_IsValidMsgId(MsgId) || (Scope > 1)) { - CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_UNSUB_ARG_ERR_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "UnSubscribe Err:Bad Arg,MsgId 0x%x,PipeId %d,app %s,scope %d", - (unsigned int)CFE_SB_MsgIdToValue(MsgId), - (int)PipeId,CFE_SB_GetAppTskName(TskId,FullName),(int)Scope); - return CFE_SB_BAD_ARGUMENT; + PendingEventID = CFE_SB_UNSUB_ARG_ERR_EID; + Status = CFE_SB_BAD_ARGUMENT; + } + else + { + /* get routing id */ + RouteId = CFE_SBR_GetRouteId(MsgId); + + /* if there have never been subscriptions for this message id... */ + if(!CFE_SBR_IsValidRouteId(RouteId)) + { + PendingEventID = CFE_SB_UNSUB_NO_SUBS_EID; + /* Status stays CFE_SUCCESS here */ + } + else + { + /* Get the destination pointer */ + DestPtr = CFE_SB_GetDestPtr(RouteId, PipeId); + + if(DestPtr != NULL) + { + /* match found, remove destination */ + CFE_SB_RemoveDest(RouteId,DestPtr); + } + else + { + PendingEventID = CFE_SB_UNSUB_NO_SUBS_EID; + } + } }/* end if */ - /* get routing id */ - RouteId = CFE_SBR_GetRouteId(MsgId); + CFE_SB_UnlockSharedData(__func__,__LINE__); - /* if there have never been subscriptions for this message id... */ - if(!CFE_SBR_IsValidRouteId(RouteId)) + if (PendingEventID != 0) { - CFE_SB_UnlockSharedData(__func__,__LINE__); - - CFE_SB_GetPipeName(PipeName, sizeof(PipeName), PipeId); + switch(PendingEventID) + { + case CFE_SB_UNSUB_NO_SUBS_EID: + CFE_SB_GetPipeName(PipeName, sizeof(PipeName), PipeId); + CFE_EVS_SendEventWithAppID(CFE_SB_UNSUB_NO_SUBS_EID,CFE_EVS_EventType_INFORMATION,CFE_SB.AppId, + "Unsubscribe Err:No subs for Msg 0x%x on %s,app %s", + (unsigned int)CFE_SB_MsgIdToValue(MsgId), + PipeName,CFE_SB_GetAppTskName(TskId,FullName)); + break; - CFE_EVS_SendEventWithAppID(CFE_SB_UNSUB_NO_SUBS_EID,CFE_EVS_EventType_INFORMATION,CFE_SB.AppId, - "Unsubscribe Err:No subs for Msg 0x%x on %s,app %s", - (unsigned int)CFE_SB_MsgIdToValue(MsgId), - PipeName,CFE_SB_GetAppTskName(TskId,FullName)); - return CFE_SUCCESS; - }/* end if */ + case CFE_SB_UNSUB_INV_PIPE_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_UNSUB_INV_PIPE_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "Unsubscribe Err:Invalid Pipe Id Msg=0x%x,Pipe=%lu,app=%s", + (unsigned int)CFE_SB_MsgIdToValue(MsgId), + CFE_ES_ResourceID_ToInteger(PipeId),CFE_SB_GetAppTskName(TskId,FullName)); + break; - /* Get the destination pointer */ - DestPtr = CFE_SB_GetDestPtr(RouteId, PipeId); + case CFE_SB_UNSUB_INV_CALLER_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_UNSUB_INV_CALLER_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "Unsubscribe Err:Caller(%s) is not the owner of pipe %lu,Msg=0x%x", + CFE_SB_GetAppTskName(TskId,FullName),CFE_ES_ResourceID_ToInteger(PipeId), + (unsigned int)CFE_SB_MsgIdToValue(MsgId)); + break; - if(DestPtr != NULL) + case CFE_SB_UNSUB_ARG_ERR_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_UNSUB_ARG_ERR_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "UnSubscribe Err:Bad Arg,MsgId 0x%x,PipeId %lu,app %s,scope %d", + (unsigned int)CFE_SB_MsgIdToValue(MsgId), + CFE_ES_ResourceID_ToInteger(PipeId),CFE_SB_GetAppTskName(TskId,FullName),(int)Scope); + break; + } + } + else if (Status == CFE_SUCCESS) { - /* match found, remove destination */ - CFE_SB_RemoveDest(RouteId,DestPtr); - + /* if no other event pending, send a debug event for successful unsubscribe */ CFE_EVS_SendEventWithAppID(CFE_SB_SUBSCRIPTION_REMOVED_EID,CFE_EVS_EventType_DEBUG,CFE_SB.AppId, - "Subscription Removed:Msg 0x%x on pipe %d,app %s", + "Subscription Removed:Msg 0x%x on pipe %lu,app %s", (unsigned int)CFE_SB_MsgIdToValue(MsgId), - (int)PipeId,CFE_SB_GetAppTskName(TskId,FullName)); + CFE_ES_ResourceID_ToInteger(PipeId),CFE_SB_GetAppTskName(TskId,FullName)); } - else - { - CFE_SB_GetPipeName(PipeName, sizeof(PipeName), PipeId); - - CFE_EVS_SendEventWithAppID(CFE_SB_UNSUB_NO_SUBS_EID,CFE_EVS_EventType_INFORMATION,CFE_SB.AppId, - "Unsubscribe Err:No subs for Msg 0x%x on %s,app %s", - (unsigned int)CFE_SB_MsgIdToValue(MsgId), - PipeName,CFE_SB_GetAppTskName(TskId,FullName)); - }/* end if */ - CFE_SB_UnlockSharedData(__func__,__LINE__); - - return CFE_SUCCESS; + return Status; }/* end CFE_SB_UnsubscribeFull */ /* @@ -1112,31 +1393,22 @@ int32 CFE_SB_TransmitMsg(CFE_MSG_Message_t *MsgPtr, bool IncrementSequenceCount CFE_SB_BufferD_t *BufDscPtr; CFE_SBR_RouteId_t RouteId; CFE_MSG_Type_t MsgType; + uint16 PendingEventID; - /* Get task id for events and Sender Info*/ - CFE_ES_GetTaskID(&TskId); + PendingEventID = 0; + BufDscPtr = NULL; Status = CFE_SB_TransmitMsgValidate(MsgPtr, &MsgId, &Size, &RouteId); - /* Copy into buffer and send if route exists */ if (Status == CFE_SUCCESS && CFE_SBR_IsValidRouteId(RouteId)) { + CFE_SB_LockSharedData(__func__, __LINE__); + /* Get buffer */ BufDscPtr = CFE_SB_GetBufferFromPool(MsgId, Size); if (BufDscPtr == NULL) { - /* Determine if event can be sent without causing recursive event problem */ - if(CFE_SB_RequestToSendEvent(TskId,CFE_SB_GET_BUF_ERR_EID_BIT) == CFE_SB_GRANTED) - { - CFE_EVS_SendEventWithAppID(CFE_SB_GET_BUF_ERR_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "Send Err:Request for Buffer Failed. MsgId 0x%x,app %s,size %d", - (unsigned int)CFE_SB_MsgIdToValue(MsgId), - CFE_SB_GetAppTskName(TskId,FullName),(int)Size); - - /* clear the bit so the task may send this event again */ - CFE_SB_FinishSendEvent(TskId,CFE_SB_GET_BUF_ERR_EID_BIT); - } - + PendingEventID = CFE_SB_GET_BUF_ERR_EID; Status = CFE_SB_BUF_ALOC_ERR; } else @@ -1148,21 +1420,43 @@ int32 CFE_SB_TransmitMsg(CFE_MSG_Message_t *MsgPtr, bool IncrementSequenceCount CFE_SBR_IncrementSequenceCounter(RouteId); CFE_MSG_SetSequenceCount(MsgPtr, CFE_SBR_GetSequenceCounter(RouteId)); } - - /* Copy data into buffer and transmit */ - memcpy(BufDscPtr->Buffer, MsgPtr, Size); - Status = CFE_SB_TransmitBufferFull(BufDscPtr, RouteId, MsgId); } + + CFE_SB_UnlockSharedData(__func__, __LINE__); + } + + if (Status == CFE_SUCCESS && BufDscPtr != NULL) + { + /* Copy data into buffer and transmit */ + memcpy(BufDscPtr->Buffer, MsgPtr, Size); + Status = CFE_SB_TransmitBufferFull(BufDscPtr, RouteId, MsgId); } if (Status != CFE_SUCCESS) { - /* Increment error counter (inside lock) if not success */ + /* Increment error counter (inside lock) if not success */ CFE_SB_LockSharedData(__func__, __LINE__); CFE_SB.HKTlmMsg.Payload.MsgSendErrorCounter++; CFE_SB_UnlockSharedData(__func__, __LINE__); } + if (PendingEventID == CFE_SB_GET_BUF_ERR_EID) + { + /* Get task id for events and Sender Info*/ + CFE_ES_GetTaskID(&TskId); + + if (CFE_SB_RequestToSendEvent(TskId,CFE_SB_GET_BUF_ERR_EID_BIT) == CFE_SB_GRANTED) + { + CFE_EVS_SendEventWithAppID(CFE_SB_GET_BUF_ERR_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "Send Err:Request for Buffer Failed. MsgId 0x%x,app %s,size %d", + (unsigned int)CFE_SB_MsgIdToValue(MsgId), + CFE_SB_GetAppTskName(TskId,FullName),(int)Size); + + /* clear the bit so the task may send this event again */ + CFE_SB_FinishSendEvent(TskId,CFE_SB_GET_BUF_ERR_EID_BIT); + } + } + return Status; } @@ -1210,67 +1504,107 @@ int32 CFE_SB_TransmitMsgValidate(CFE_MSG_Message_t *MsgPtr, { CFE_ES_ResourceID_t TskId; char FullName[(OS_MAX_API_NAME * 2)]; + uint16 PendingEventID; + int32 Status; - /* get task id for events and Sender Info*/ - CFE_ES_GetTaskID(&TskId); + PendingEventID = 0; + Status = CFE_SUCCESS; /* check input parameter */ - if(MsgPtr == NULL) + if (MsgPtr == NULL) { - CFE_EVS_SendEventWithAppID(CFE_SB_SEND_BAD_ARG_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "Send Err:Bad input argument,Arg 0x%lx,App %s", - (unsigned long)MsgPtr,CFE_SB_GetAppTskName(TskId,FullName)); - return CFE_SB_BAD_ARGUMENT; - }/* end if */ - - CFE_MSG_GetMsgId(MsgPtr, MsgIdPtr); + PendingEventID = CFE_SB_SEND_BAD_ARG_EID; + Status = CFE_SB_BAD_ARGUMENT; + } - /* validate the msgid in the message */ - if(!CFE_SB_IsValidMsgId(*MsgIdPtr)) + if (Status == CFE_SUCCESS) { - CFE_EVS_SendEventWithAppID(CFE_SB_SEND_INV_MSGID_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "Send Err:Invalid MsgId(0x%x)in msg,App %s", - (unsigned int)CFE_SB_MsgIdToValue(*MsgIdPtr), - CFE_SB_GetAppTskName(TskId,FullName)); - return CFE_SB_BAD_ARGUMENT; - }/* end if */ + CFE_MSG_GetMsgId(MsgPtr, MsgIdPtr); - CFE_MSG_GetSize(MsgPtr, SizePtr); + /* validate the msgid in the message */ + if(!CFE_SB_IsValidMsgId(*MsgIdPtr)) + { + PendingEventID = CFE_SB_SEND_INV_MSGID_EID; + Status = CFE_SB_BAD_ARGUMENT; + } + } - /* Verify the size of the pkt is < or = the mission defined max */ - if(*SizePtr > CFE_MISSION_SB_MAX_SB_MSG_SIZE) + if (Status == CFE_SUCCESS) { - CFE_EVS_SendEventWithAppID(CFE_SB_MSG_TOO_BIG_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "Send Err:Msg Too Big MsgId=0x%x,app=%s,size=%d,MaxSz=%d", - (unsigned int)CFE_SB_MsgIdToValue(*MsgIdPtr), - CFE_SB_GetAppTskName(TskId,FullName),(int)*SizePtr,CFE_MISSION_SB_MAX_SB_MSG_SIZE); - return CFE_SB_MSG_TOO_BIG; - }/* end if */ + CFE_MSG_GetSize(MsgPtr, SizePtr); + + /* Verify the size of the pkt is < or = the mission defined max */ + if(*SizePtr > CFE_MISSION_SB_MAX_SB_MSG_SIZE) + { + PendingEventID = CFE_SB_MSG_TOO_BIG_EID; + Status = CFE_SB_MSG_TOO_BIG; + }/* end if */ + } + + if (Status == CFE_SUCCESS) + { + /* check the route, which should be done while locked */ + CFE_SB_LockSharedData(__func__, __LINE__); + + /* Get the routing id */ + *RouteIdPtr = CFE_SBR_GetRouteId(*MsgIdPtr); - /* Get the routing id */ - *RouteIdPtr = CFE_SBR_GetRouteId(*MsgIdPtr); + /* if there have been no subscriptions for this pkt, */ + /* increment the dropped pkt cnt, send event and return success */ + if(!CFE_SBR_IsValidRouteId(*RouteIdPtr)) + { + CFE_SB.HKTlmMsg.Payload.NoSubscribersCounter++; + PendingEventID = CFE_SB_SEND_NO_SUBS_EID; + } + + CFE_SB_UnlockSharedData(__func__, __LINE__); + } + + if (PendingEventID != 0) + { + /* get task id for events */ + CFE_ES_GetTaskID(&TskId); - /* if there have been no subscriptions for this pkt, */ - /* increment the dropped pkt cnt, send event and return success */ - if(!CFE_SBR_IsValidRouteId(*RouteIdPtr)){ + switch (PendingEventID) + { + case CFE_SB_SEND_BAD_ARG_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_SEND_BAD_ARG_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "Send Err:Bad input argument,Arg 0x%lx,App %s", + (unsigned long)MsgPtr,CFE_SB_GetAppTskName(TskId,FullName)); + break; - CFE_SB.HKTlmMsg.Payload.NoSubscribersCounter++; + case CFE_SB_SEND_INV_MSGID_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_SEND_INV_MSGID_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "Send Err:Invalid MsgId(0x%x)in msg,App %s", + (unsigned int)CFE_SB_MsgIdToValue(*MsgIdPtr), + CFE_SB_GetAppTskName(TskId,FullName)); + break; - /* Determine if event can be sent without causing recursive event problem */ - if(CFE_SB_RequestToSendEvent(TskId,CFE_SB_SEND_NO_SUBS_EID_BIT) == CFE_SB_GRANTED){ + case CFE_SB_MSG_TOO_BIG_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_MSG_TOO_BIG_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "Send Err:Msg Too Big MsgId=0x%x,app=%s,size=%d,MaxSz=%d", + (unsigned int)CFE_SB_MsgIdToValue(*MsgIdPtr), + CFE_SB_GetAppTskName(TskId,FullName),(int)*SizePtr,CFE_MISSION_SB_MAX_SB_MSG_SIZE); + break; - CFE_EVS_SendEventWithAppID(CFE_SB_SEND_NO_SUBS_EID,CFE_EVS_EventType_INFORMATION,CFE_SB.AppId, - "No subscribers for MsgId 0x%x,sender %s", - (unsigned int)CFE_SB_MsgIdToValue(*MsgIdPtr), - CFE_SB_GetAppTskName(TskId,FullName)); + case CFE_SB_SEND_NO_SUBS_EID: + /* Determine if event can be sent without causing recursive event problem */ + if (CFE_SB_RequestToSendEvent(TskId,CFE_SB_SEND_NO_SUBS_EID_BIT) == CFE_SB_GRANTED) + { + CFE_EVS_SendEventWithAppID(CFE_SB_SEND_NO_SUBS_EID,CFE_EVS_EventType_INFORMATION,CFE_SB.AppId, + "No subscribers for MsgId 0x%x,sender %s", + (unsigned int)CFE_SB_MsgIdToValue(*MsgIdPtr), + CFE_SB_GetAppTskName(TskId,FullName)); - /* clear the bit so the task may send this event again */ - CFE_SB_FinishSendEvent(TskId,CFE_SB_SEND_NO_SUBS_EID_BIT); - }/* end if */ + /* clear the bit so the task may send this event again */ + CFE_SB_FinishSendEvent(TskId,CFE_SB_SEND_NO_SUBS_EID_BIT); + }/* end if */ + break; + } }/* end if */ - return CFE_SUCCESS; + return Status; } /*****************************************************************************/ @@ -1290,12 +1624,14 @@ int32 CFE_SB_TransmitBufferFull(CFE_SB_BufferD_t *BufDscPtr, CFE_ES_ResourceID_t TskId; CFE_SB_DestinationD_t *DestPtr; CFE_SB_PipeD_t *PipeDscPtr; - CFE_SB_EventBuf_t SBSndErr = {0}; - char PipeName[OS_MAX_API_NAME] = {'\0'}; - CFE_SB_PipeDepthStats_t *StatObj; + CFE_SB_EventBuf_t SBSndErr; int32 Status; uint32 i; char FullName[(OS_MAX_API_NAME * 2)]; + char PipeName[OS_MAX_API_NAME]; + + Status = CFE_SUCCESS; + SBSndErr.EvtsToSnd = 0; /* get app id for loopback testing */ CFE_ES_GetAppID(&AppId); @@ -1309,23 +1645,30 @@ int32 CFE_SB_TransmitBufferFull(CFE_SB_BufferD_t *BufDscPtr, /* Send the packet to all destinations */ for(DestPtr = CFE_SBR_GetDestListHeadPtr(RouteId); DestPtr != NULL; DestPtr = DestPtr->Next) { - if (DestPtr->Active == CFE_SB_INACTIVE) /* destination is active */ + if (DestPtr->Active == CFE_SB_ACTIVE) /* destination is active */ { - continue; - }/*end if */ + PipeDscPtr = CFE_SB_LocatePipeDescByID(DestPtr->PipeId); + } + else + { + PipeDscPtr = NULL; + } - PipeDscPtr = &CFE_SB.PipeTbl[DestPtr->PipeId]; + if (!CFE_SB_PipeDescIsMatch(PipeDscPtr, DestPtr->PipeId)) + { + continue; + } if((PipeDscPtr->Opts & CFE_SB_PIPEOPTS_IGNOREMINE) != 0 && - CFE_ES_ResourceID_Equal(PipeDscPtr->AppId, AppId)) + CFE_ES_ResourceID_Equal(PipeDscPtr->AppId, AppId)) { continue; }/* end if */ /* if Msg limit exceeded, log event, increment counter */ /* and go to next destination */ - if(DestPtr->BuffCount >= DestPtr->MsgId2PipeLim){ - + if(DestPtr->BuffCount >= DestPtr->MsgId2PipeLim) + { SBSndErr.EvtBuf[SBSndErr.EvtsToSnd].PipeId = DestPtr->PipeId; SBSndErr.EvtBuf[SBSndErr.EvtsToSnd].EventId = CFE_SB_MSGID_LIM_ERR_EID; SBSndErr.EvtsToSnd++; @@ -1343,38 +1686,42 @@ int32 CFE_SB_TransmitBufferFull(CFE_SB_BufferD_t *BufDscPtr, if (Status == OS_SUCCESS) { - BufDscPtr->UseCount++; /* used for releasing buffer */ + /* The queue now holds a ref to the buffer, so increment its ref count. */ + CFE_SB_IncrBufUseCnt(BufDscPtr); + DestPtr->BuffCount++; /* used for checking MsgId2PipeLimit */ DestPtr->DestCnt++; /* used for statistics */ - if (DestPtr->PipeId < CFE_SB_TLM_PIPEDEPTHSTATS_SIZE) + ++PipeDscPtr->QueueDepth; + if (PipeDscPtr->QueueDepth >= PipeDscPtr->PeakDepth) { - StatObj = &CFE_SB.StatTlmMsg.Payload.PipeDepthStats[DestPtr->PipeId]; - StatObj->InUse++; - if(StatObj->InUse > StatObj->PeakInUse) - { - StatObj->PeakInUse = StatObj->InUse; - }/* end if */ + PipeDscPtr->PeakDepth = PipeDscPtr->QueueDepth; } + + Status = CFE_SUCCESS; } - else if(Status == OS_QUEUE_FULL) + else { - SBSndErr.EvtBuf[SBSndErr.EvtsToSnd].PipeId = DestPtr->PipeId; - SBSndErr.EvtBuf[SBSndErr.EvtsToSnd].EventId = CFE_SB_Q_FULL_ERR_EID; - SBSndErr.EvtsToSnd++; - CFE_SB.HKTlmMsg.Payload.PipeOverflowErrorCounter++; - PipeDscPtr->SendErrors++; + if (Status == OS_QUEUE_FULL) + { + SBSndErr.EvtBuf[SBSndErr.EvtsToSnd].PipeId = DestPtr->PipeId; + SBSndErr.EvtBuf[SBSndErr.EvtsToSnd].EventId = CFE_SB_Q_FULL_ERR_EID; + SBSndErr.EvtsToSnd++; + CFE_SB.HKTlmMsg.Payload.PipeOverflowErrorCounter++; + PipeDscPtr->SendErrors++; + } + else + { + /* Unexpected error while writing to queue. */ + SBSndErr.EvtBuf[SBSndErr.EvtsToSnd].PipeId = DestPtr->PipeId; + SBSndErr.EvtBuf[SBSndErr.EvtsToSnd].EventId = CFE_SB_Q_WR_ERR_EID; + SBSndErr.EvtBuf[SBSndErr.EvtsToSnd].ErrStat = Status; + SBSndErr.EvtsToSnd++; + CFE_SB.HKTlmMsg.Payload.InternalErrorCounter++; + PipeDscPtr->SendErrors++; + }/*end if */ + + Status = CFE_STATUS_EXTERNAL_RESOURCE_FAIL; } - else - { - /* Unexpected error while writing to queue. */ - SBSndErr.EvtBuf[SBSndErr.EvtsToSnd].PipeId = DestPtr->PipeId; - SBSndErr.EvtBuf[SBSndErr.EvtsToSnd].EventId = CFE_SB_Q_WR_ERR_EID; - SBSndErr.EvtBuf[SBSndErr.EvtsToSnd].ErrStat = Status; - SBSndErr.EvtsToSnd++; - CFE_SB.HKTlmMsg.Payload.InternalErrorCounter++; - PipeDscPtr->SendErrors++; - }/*end if */ - } /* end loop over destinations */ /* @@ -1472,120 +1819,252 @@ int32 CFE_SB_ReceiveBuffer(CFE_SB_Buffer_t **BufPtr, int32 TimeOut) { int32 Status; - CFE_SB_BufferD_t *Message; + int32 RcvStatus; + CFE_SB_BufferD_t *BufDscPtr; + size_t BufDscSize; CFE_SB_PipeD_t *PipeDscPtr; - CFE_SB_DestinationD_t *DestPtr = NULL; + CFE_SB_DestinationD_t *DestPtr; CFE_SBR_RouteId_t RouteId; CFE_ES_ResourceID_t TskId; + uint16 PendingEventID; + osal_id_t SysQueueId; + int32 SysTimeout; char FullName[(OS_MAX_API_NAME * 2)]; - /* get task id for events */ - CFE_ES_GetTaskID(&TskId); - - /* Check input parameters */ - if((BufPtr == NULL)||(TimeOut < (-1))){ - CFE_SB_LockSharedData(__func__,__LINE__); - CFE_SB.HKTlmMsg.Payload.MsgReceiveErrorCounter++; - CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_RCV_BAD_ARG_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "Rcv Err:Bad Input Arg:BufPtr 0x%lx,pipe %d,t/o %d,app %s", - (unsigned long)BufPtr,(int)PipeId,(int)TimeOut,CFE_SB_GetAppTskName(TskId,FullName)); - return CFE_SB_BAD_ARGUMENT; - }/* end if */ - - PipeDscPtr = CFE_SB_GetPipePtr(PipeId); - /* If the pipe does not exist or PipeId is out of range... */ - if (PipeDscPtr == NULL) { - CFE_SB_LockSharedData(__func__,__LINE__); - CFE_SB.HKTlmMsg.Payload.MsgReceiveErrorCounter++; - CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEventWithAppID(CFE_SB_BAD_PIPEID_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "Rcv Err:PipeId %d does not exist,app %s", - (int)PipeId,CFE_SB_GetAppTskName(TskId,FullName)); - return CFE_SB_BAD_ARGUMENT; - }/* end if */ - - /* - ** Save off any currently in use buffer to free later; this allows - ** one fewer shared data locks - */ - - PipeDscPtr->ToTrashBuff = PipeDscPtr->CurrentBuff; - PipeDscPtr->CurrentBuff = NULL; - + PendingEventID = 0; + Status = CFE_SUCCESS; + SysTimeout = OS_PEND; + SysQueueId = OS_OBJECT_ID_UNDEFINED; + PipeDscPtr = NULL; + BufDscPtr = NULL; + DestPtr = NULL; + BufDscSize = 0; + /* - ** Read a new buffer from the queue of the pipe, using the - ** specified timeout option. If a buffer was obtained, return the - ** packet to the task according to mode. Otherwise, return a status - ** code indicating that no buffer was read. - */ - Status = CFE_SB_ReadQueue(PipeDscPtr, TskId, TimeOut, &Message); - - /* take semaphore again to protect the remaining code in this call */ - CFE_SB_LockSharedData(__func__,__LINE__); - - /* free any pending trash buffer */ - if (PipeDscPtr->ToTrashBuff != NULL) { - - /* Decrement the Buffer Use Count and Free buffer if cnt=0) */ - CFE_SB_DecrBufUseCnt(PipeDscPtr->ToTrashBuff); + * Check input args and see if any are bad, which require + * a "BAD_ARG_EID" to be generated. + * + * Also translate the timeout here. Timeouts greater than 0 + * may be passed to OSAL directly, but the two fixed constants + * CFE_SB_PEND_FOREVER and CFE_SB_POLL are checked explicitly, + * to maintain API independence - even though the values are + * currently defined the same. + */ - PipeDscPtr->ToTrashBuff = NULL; + if (BufPtr == NULL) + { + PendingEventID = CFE_SB_RCV_BAD_ARG_EID; + Status = CFE_SB_BAD_ARGUMENT; + } + else if (TimeOut > 0) + { + /* time outs greater than 0 can be passed to OSAL directly */ + SysTimeout = TimeOut; + } + else if (TimeOut == CFE_SB_POLL) + { + SysTimeout = OS_CHECK; + } + else if (TimeOut != CFE_SB_PEND_FOREVER) + { + /* any other timeout value is invalid */ + PendingEventID = CFE_SB_RCV_BAD_ARG_EID; + Status = CFE_SB_BAD_ARGUMENT; + } - }/* end if */ + /* If OK, then lock and pull relevent info from Pipe Descriptor */ + if (Status == CFE_SUCCESS) + { + CFE_SB_LockSharedData(__func__,__LINE__); - if (Status == CFE_SUCCESS) { + PipeDscPtr = CFE_SB_LocatePipeDescByID(PipeId); - /* - ** Load the pipe tables 'CurrentBuff' with the buffer descriptor - ** ptr corresponding to the message just read. This is done so that - ** the buffer can be released on the next receive call for this pipe. - */ - PipeDscPtr->CurrentBuff = Message; + /* If the pipe does not exist or PipeId is out of range... */ + if(!CFE_SB_PipeDescIsMatch(PipeDscPtr, PipeId)) + { + PendingEventID = CFE_SB_BAD_PIPEID_EID; + Status = CFE_SB_BAD_ARGUMENT; + } + else + { + /* Grab the queue ID */ + SysQueueId = PipeDscPtr->SysQueueId; + + /* + * Un-reference any previous buffer from the last call. + * + * NOTE: This is historical behavior where apps call CFE_SB_ReceiveBuffer() + * in the loop within the app's main task. There is currently no separate + * API to "free" or unreference a buffer that was returned from SB. + * + * Instead, each time this function is invoked, it is implicitly interpreted + * as an indication that the caller is done with the previous buffer. + * + * Unfortunately this prevents pipe IDs from being serviced/shared across + * multiple child tasks in a worker pattern design. This may be changed + * in a future version of CFE to decouple these actions, to allow for + * multiple workers to service the same pipe. + */ + if (PipeDscPtr->LastBuffer != NULL) + { + /* Decrement the Buffer Use Count, which will Free buffer if it becomes 0 */ + CFE_SB_DecrBufUseCnt(PipeDscPtr->LastBuffer); + PipeDscPtr->LastBuffer = NULL; + } + } - /* Set the Receivers pointer to the address of the actual message */ - *BufPtr = (CFE_SB_Buffer_t *) Message->Buffer; + CFE_SB_UnlockSharedData(__func__,__LINE__); + } - /* get pointer to destination to be used in decrementing msg limit cnt*/ - RouteId = CFE_SBR_GetRouteId(PipeDscPtr->CurrentBuff->MsgId); - DestPtr = CFE_SB_GetDestPtr(RouteId, PipeDscPtr->PipeId); + /* + * If everything validated, then proceed to get a buffer from the queue. + * This must be done OUTSIDE the SB lock, as this call likely blocks. + */ + if (Status == CFE_SUCCESS) + { + /* Read the buffer descriptor address from the queue. */ + RcvStatus = OS_QueueGet(SysQueueId, + &BufDscPtr, + sizeof(BufDscPtr), + &BufDscSize, + SysTimeout); + + /* + * translate the return value - + * + * CFE functions have their own set of RC values should not directly return OSAL codes + * The size should always match. If it does not, then generate CFE_SB_Q_RD_ERR_EID. + */ + if(RcvStatus == OS_SUCCESS && BufDscPtr != NULL && BufDscSize == sizeof(BufDscPtr)) + { + /* Pass through */ + } + else if (RcvStatus == OS_QUEUE_EMPTY) + { + /* normal if using CFE_SB_POLL */ + Status = CFE_SB_NO_MESSAGE; + } + else if (RcvStatus == OS_QUEUE_TIMEOUT) + { + /* normal if using a nonzero timeout */ + Status = CFE_SB_TIME_OUT; + } + else + { + /* off-nominal condition, report an error event */ + PendingEventID = CFE_SB_Q_RD_ERR_EID; + Status = CFE_SB_PIPE_RD_ERR; + } + } - /* - ** DestPtr would be NULL if the msg is unsubscribed to while it is on - ** the pipe. The BuffCount may be zero if the msg is unsubscribed to and - ** then resubscribed to while it is on the pipe. Both of these cases are - ** considered nominal and are handled by the code below. - */ - if(DestPtr != NULL){ + /* Now re-lock to store the buffer in the pipe descriptor */ + CFE_SB_LockSharedData(__func__,__LINE__); - if (DestPtr->BuffCount > 0){ + if (Status == CFE_SUCCESS) + { + /* + * NOTE: This uses the same PipeDscPtr that was found earlier. + * Technically it is possible that the pipe was changed between now and then, + * but the current PipeID definition doesn't really allow this to be detected. + */ + if (CFE_SB_PipeDescIsMatch(PipeDscPtr, PipeId)) + { + /* + ** Load the pipe tables 'CurrentBuff' with the buffer descriptor + ** ptr corresponding to the message just read. This is done so that + ** the buffer can be released on the next receive call for this pipe. + ** + ** This counts as a new reference as it is being stored in the PipeDsc + */ + CFE_SB_IncrBufUseCnt(BufDscPtr); + PipeDscPtr->LastBuffer = BufDscPtr; + + /* + * Also set the Receivers pointer to the address of the actual message + * (currently this is "borrowing" the ref above, not its own ref) + */ + *BufPtr = BufDscPtr->Buffer; + + /* get pointer to destination to be used in decrementing msg limit cnt*/ + RouteId = CFE_SBR_GetRouteId(BufDscPtr->MsgId); + DestPtr = CFE_SB_GetDestPtr(RouteId, PipeId); + + /* + ** DestPtr would be NULL if the msg is unsubscribed to while it is on + ** the pipe. The BuffCount may be zero if the msg is unsubscribed to and + ** then resubscribed to while it is on the pipe. Both of these cases are + ** considered nominal and are handled by the code below. + */ + if (DestPtr != NULL && DestPtr->BuffCount > 0) + { DestPtr->BuffCount--; } - }/* end if DestPtr != NULL */ + if (PipeDscPtr->CurrentDepth > 0) + { + --PipeDscPtr->CurrentDepth; + } + } + else + { + /* should send the bad pipe ID event here too */ + PendingEventID = CFE_SB_BAD_PIPEID_EID; + Status = CFE_SB_PIPE_RD_ERR; + } + + /* Always decrement the use count, for the ref that was in the queue */ + CFE_SB_DecrBufUseCnt(BufDscPtr); + } - if (PipeDscPtr->PipeId < CFE_SB_TLM_PIPEDEPTHSTATS_SIZE) + /* Before unlocking, check the PendingEventID and increment relevant error counter */ + if (Status != CFE_SUCCESS) + { + if (PendingEventID == CFE_SB_RCV_BAD_ARG_EID || PendingEventID == CFE_SB_BAD_PIPEID_EID) + { + ++CFE_SB.HKTlmMsg.Payload.MsgReceiveErrorCounter; + } + else { - CFE_SB.StatTlmMsg.Payload.PipeDepthStats[PipeDscPtr->PipeId].InUse--; + /* For any other unexpected error (e.g. CFE_SB_Q_RD_ERR_EID) */ + ++CFE_SB.HKTlmMsg.Payload.InternalErrorCounter; } + } - }else{ + CFE_SB_UnlockSharedData(__func__,__LINE__); - /* Set the users pointer to NULL indicating the CFE_SB_ReadQueue failed */ - *BufPtr = NULL; + /* Now actually send the event, after unlocking (do not call EVS with SB locked) */ + if (PendingEventID != 0) + { + /* get task id for events */ + CFE_ES_GetTaskID(&TskId); - }/* end if */ + switch(PendingEventID) + { + case CFE_SB_Q_RD_ERR_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_Q_RD_ERR_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "Pipe Read Err,pipe %lu,app %s,stat 0x%x", + CFE_ES_ResourceID_ToInteger(PipeId),CFE_SB_GetAppTskName(TskId,FullName),(unsigned int)RcvStatus); + break; + case CFE_SB_RCV_BAD_ARG_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_RCV_BAD_ARG_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "Rcv Err:Bad Input Arg:BufPtr 0x%lx,pipe %lu,t/o %d,app %s", + (unsigned long)BufPtr,CFE_ES_ResourceID_ToInteger(PipeId),(int)TimeOut,CFE_SB_GetAppTskName(TskId,FullName)); + break; + case CFE_SB_BAD_PIPEID_EID: + CFE_EVS_SendEventWithAppID(CFE_SB_BAD_PIPEID_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, + "Rcv Err:PipeId %lu does not exist,app %s", + CFE_ES_ResourceID_ToInteger(PipeId),CFE_SB_GetAppTskName(TskId,FullName)); + break; + } + } - /* release the semaphore */ - CFE_SB_UnlockSharedData(__func__,__LINE__); + /* If not successful, set the output pointer to NULL */ + if (Status != CFE_SUCCESS && BufPtr != NULL) + { + *BufPtr = NULL; + } - /* - ** If status is not CFE_SUCCESS, then no packet was received. If this was - ** caused by an unexpected error, then CFE_SB_ReadQueue() will report the - ** error. - */ return Status; - } @@ -1672,7 +2151,7 @@ CFE_SB_Buffer_t *CFE_SB_ZeroCopyGetPtr(size_t MsgSize, /* Initialize the buffer descriptor structure. */ bd->UseCount = 1; bd->Size = MsgSize; - bd->Buffer = (void *)address; + bd->Buffer = (CFE_SB_Buffer_t *)address; return (CFE_SB_Buffer_t *)address; @@ -1862,99 +2341,3 @@ int32 CFE_SB_ZeroCopyPass(CFE_SB_Buffer_t *BufPtr, }/* end CFE_SB_ZeroCopyPass */ #endif - -/****************************************************************************** -** Function: CFE_SB_ReadQueue() -** -** Purpose: -** Read an SB message from the system queue. The message is represented -** by a pointer to the buffer descriptor of the message. Several options -** are available for the timeout, as described below. -** -** Arguments: -** PipeDscPtr: Pointer to pipe descriptor. -** AppId : Application ID of the receiving task (used for error messages). -** Time_Out : Timeout option; one of the following: -** CFE_SB_PEND_FOREVER = wait forever until a packet arrives -** CFE_SB_POLL = check the pipe for packets but don't wait -** value in milliseconds = wait up to a specified time -** Message : Pointer to a variable that will receive the buffer -** descriptor of the message. -** -** Return: -** CFE_SB status code indicating the result of the operation: -** CFE_SUCCESS = message was successfully read -** CFE_SB_NO_MESSAGE = no message is present (for CFE_SB_POLL option) -** CFE_SB_TIME_OUT = timeout expired (for timeout option) -** CFE_SB_PIPE_RD_ERR = an unexpected queue read error occurred -*/ - -int32 CFE_SB_ReadQueue (CFE_SB_PipeD_t *PipeDscPtr, - CFE_ES_ResourceID_t TskId, - uint32 Time_Out, - CFE_SB_BufferD_t **Message) -{ - int32 Status,TimeOut; - size_t Nbytes; - char FullName[(OS_MAX_API_NAME * 2)]; - char PipeName[OS_MAX_API_NAME] = {'\0'}; - - /* translate the given Time_Out value */ - switch(Time_Out){ - - case CFE_SB_PEND_FOREVER: - TimeOut = OS_PEND; - break; - - case CFE_SB_POLL: - TimeOut = OS_CHECK; - break; - - default: - TimeOut = Time_Out; - break; - - }/* end switch */ - - /* Read the buffer descriptor address from the queue. */ - Status = OS_QueueGet(PipeDscPtr->SysQueueId, - (void *)Message, - sizeof(CFE_SB_BufferD_t *), - &Nbytes, - TimeOut); - - /* translate the return value */ - switch(Status){ - - case OS_SUCCESS: - Status = CFE_SUCCESS; - break; - - case OS_QUEUE_EMPTY: - Status = CFE_SB_NO_MESSAGE; - break; - - case OS_QUEUE_TIMEOUT: - Status = CFE_SB_TIME_OUT; - break; - - default: - CFE_SB_LockSharedData(__func__,__LINE__); - CFE_SB.HKTlmMsg.Payload.InternalErrorCounter++; - CFE_SB_UnlockSharedData(__func__,__LINE__); - /* Unexpected error while reading the queue. */ - CFE_SB_GetPipeName(PipeName, sizeof(PipeName), PipeDscPtr->PipeId); - CFE_EVS_SendEventWithAppID(CFE_SB_Q_RD_ERR_EID,CFE_EVS_EventType_ERROR,CFE_SB.AppId, - "Pipe Read Err,pipe %s,app %s,stat 0x%x", - PipeName,CFE_SB_GetAppTskName(TskId,FullName),(unsigned int)Status); - - Status = CFE_SB_PIPE_RD_ERR; - break; - - }/* end switch */ - - return (Status); -}/* end CFE_SB_ReadQueue */ - -/*****************************************************************************/ - diff --git a/fsw/cfe-core/src/sb/cfe_sb_buf.c b/fsw/cfe-core/src/sb/cfe_sb_buf.c index e213a12e6..8bb1b7a83 100644 --- a/fsw/cfe-core/src/sb/cfe_sb_buf.c +++ b/fsw/cfe-core/src/sb/cfe_sb_buf.c @@ -91,7 +91,7 @@ CFE_SB_BufferD_t * CFE_SB_GetBufferFromPool(CFE_SB_MsgId_t MsgId, size_t Size) { bd->MsgId = MsgId; bd->UseCount = 1; bd->Size = Size; - bd->Buffer = (void *)address; + bd->Buffer = (CFE_SB_Buffer_t *)address; return bd; @@ -156,6 +156,32 @@ int32 CFE_SB_ReturnBufferToPool(CFE_SB_BufferD_t *bd){ }/* end CFE_SB_ReturnBufferToPool */ +/****************************************************************************** +** Function: CFE_SB_IncrBufUseCnt() +** +** Purpose: +** This function will increment the UseCount of a particular buffer. +** +** Note: +** UseCount is a variable in the CFE_SB_BufferD_t and is used only to +** determine when a buffer may be returned to the memory pool. +** +** Arguments: +** bd : Pointer to the buffer descriptor. +** +** Return: +** CFE_SUCCESS for normal operation. +*/ +void CFE_SB_IncrBufUseCnt(CFE_SB_BufferD_t *bd) +{ + /* range check the UseCount variable */ + if(bd->UseCount < 0x7FFF) + { + ++bd->UseCount; + } + +}/* end CFE_SB_DecrBufUseCnt */ + /****************************************************************************** ** Function: CFE_SB_DecrBufUseCnt() @@ -175,21 +201,19 @@ int32 CFE_SB_ReturnBufferToPool(CFE_SB_BufferD_t *bd){ ** Return: ** CFE_SUCCESS for normal operation. */ -int32 CFE_SB_DecrBufUseCnt(CFE_SB_BufferD_t *bd){ - +void CFE_SB_DecrBufUseCnt(CFE_SB_BufferD_t *bd) +{ /* range check the UseCount variable */ - if(bd->UseCount > 0){ - - bd->UseCount--; + if(bd->UseCount > 0) + { + --bd->UseCount; - if (bd->UseCount == 0) { + if (bd->UseCount == 0) + { CFE_SB_ReturnBufferToPool(bd); - }/* end if */ - + } } - return CFE_SUCCESS; - }/* end CFE_SB_DecrBufUseCnt */ diff --git a/fsw/cfe-core/src/sb/cfe_sb_init.c b/fsw/cfe-core/src/sb/cfe_sb_init.c index e9a35cfb4..b5b2c1a4a 100644 --- a/fsw/cfe-core/src/sb/cfe_sb_init.c +++ b/fsw/cfe-core/src/sb/cfe_sb_init.c @@ -87,6 +87,9 @@ int32 CFE_SB_EarlyInit (void) { int32 Stat; + /* ensure entire CFE_SB global data structure is purged first */ + memset(&CFE_SB, 0, sizeof(CFE_SB)); + CFE_SB_Default_Qos.Priority = CFE_SB_QOS_LOW_PRIORITY; CFE_SB_Default_Qos.Reliability = CFE_SB_QOS_LOW_RELIABILITY; @@ -178,16 +181,9 @@ int32 CFE_SB_InitBuffers(void) { ** Return: ** none */ -void CFE_SB_InitPipeTbl(void){ - - uint8 i; - - for(i=0;i /****************************************************************************** @@ -97,88 +98,43 @@ ** Return: ** None */ -int32 CFE_SB_CleanUpApp(CFE_ES_ResourceID_t AppId){ - - uint32 i; - - /* loop through the pipe table looking for pipes owned by AppId */ - for(i=0;iAppId, AppId)) + { + DelList[DelCount] = CFE_SB_PipeDescGetID(PipeDscPtr); + ++DelCount; + } + ++PipeDscPtr; + } - /* search the pipe table for the for the given pipe id */ - for(i=0;iPipeId == PipeId) + if( CFE_ES_ResourceID_Equal(destptr->PipeId, PipeId) ) { break; } @@ -348,31 +274,39 @@ int32 CFE_SB_ValidateMsgId(CFE_SB_MsgId_t MsgId){ }/* end CFE_SB_ValidateMsgId */ +/*********************************************************************/ +/* + * CFE_SB_LocatePipeDescByID + * + * For complete API information, see prototype in header + */ +CFE_SB_PipeD_t *CFE_SB_LocatePipeDescByID(CFE_SB_PipeId_t PipeId) +{ + CFE_SB_PipeD_t *PipeDscPtr; + uint32 Idx; -/****************************************************************************** -** Function: CFE_SB_ValidatePipeId() -** -** Purpose: -** This function checks that the pipe id does not have an index larger than the -** array and that the pipe is in use. -** -** Arguments: -** -** Return: -** None -*/ -int32 CFE_SB_ValidatePipeId(CFE_SB_PipeId_t PipeId){ - - if((PipeId >= CFE_PLATFORM_SB_MAX_PIPES)|| - (CFE_SB.PipeTbl[PipeId].InUse == CFE_SB_NOT_IN_USE)) + if (CFE_SB_PipeId_ToIndex(PipeId, &Idx) == CFE_SUCCESS) { - return CFE_SB_FAILED; - }else{ - return CFE_SUCCESS; - }/* end if */ + PipeDscPtr = &CFE_SB.PipeTbl[Idx]; + } + else + { + PipeDscPtr = NULL; + } -}/* end CFE_SB_ValidatePipeId */ + return PipeDscPtr; +} +/*********************************************************************/ +/* + * CFE_SB_CheckPipeDescSlotUsed + * + * Checks if a table slot is used or not (helper for allocating IDs) + */ +bool CFE_SB_CheckPipeDescSlotUsed(CFE_SB_PipeId_t CheckId) +{ + return CFE_SB_PipeDescIsUsed(CFE_SB_LocatePipeDescByID(CheckId)); +} /****************************************************************************** ** Function: CFE_SB_GetAppTskName() @@ -618,4 +552,3 @@ int32 CFE_SB_ZeroCopyReleaseAppId(CFE_ES_ResourceID_t AppId) }/* end CFE_SB_ZeroCopyReleasePtr */ /*****************************************************************************/ - diff --git a/fsw/cfe-core/src/sb/cfe_sb_priv.h b/fsw/cfe-core/src/sb/cfe_sb_priv.h index f8a0ff05a..4888434f1 100644 --- a/fsw/cfe-core/src/sb/cfe_sb_priv.h +++ b/fsw/cfe-core/src/sb/cfe_sb_priv.h @@ -43,13 +43,13 @@ #include "cfe_time.h" #include "cfe_es.h" #include "private/cfe_sbr.h" +#include "private/cfe_resourceid_internal.h" /* ** Macro Definitions */ #define CFE_SB_UNUSED_QUEUE OS_OBJECT_ID_UNDEFINED -#define CFE_SB_INVALID_PIPE 0xFF #define CFE_SB_NO_DESTINATION 0xFF #define CFE_SB_FAILED 1 #define SB_DONT_CARE 0 @@ -117,7 +117,7 @@ typedef struct { CFE_SB_MsgId_t MsgId; uint16 UseCount; size_t Size; - void *Buffer; + CFE_SB_Buffer_t *Buffer; } CFE_SB_BufferD_t; /****************************************************************************** @@ -148,18 +148,16 @@ typedef struct { */ typedef struct { - uint8 InUse; - CFE_SB_PipeId_t PipeId; - char AppName[OS_MAX_API_NAME]; - uint8 Opts; - uint8 Spare; + CFE_SB_PipeId_t PipeId; + uint8 Opts; + uint8 Spare; CFE_ES_ResourceID_t AppId; - osal_id_t SysQueueId; - uint32 LastSender; - uint16 QueueDepth; - uint16 SendErrors; - CFE_SB_BufferD_t *CurrentBuff; - CFE_SB_BufferD_t *ToTrashBuff; + osal_id_t SysQueueId; + uint16 QueueDepth; + uint16 SendErrors; + uint16 CurrentDepth; + uint16 PeakDepth; + CFE_SB_BufferD_t *LastBuffer; } CFE_SB_PipeD_t; /****************************************************************************** @@ -196,8 +194,8 @@ typedef struct CFE_SB_PipeId_t CmdPipe; CFE_SB_MemParams_t Mem; CFE_SB_AllSubscriptionsTlm_t PrevSubMsg; - CFE_SB_SingleSubscriptionTlm_t SubRprtMsg; CFE_EVS_BinFilter_t EventFilters[CFE_SB_MAX_CFG_FILE_EVENTS_TO_FILTER]; + CFE_SB_PipeId_t LastPipeId; } cfe_sb_t; @@ -238,11 +236,8 @@ void CFE_SB_ResetCounts(void); void CFE_SB_LockSharedData(const char *FuncName, int32 LineNumber); void CFE_SB_UnlockSharedData(const char *FuncName, int32 LineNumber); void CFE_SB_ReleaseBuffer (CFE_SB_BufferD_t *bd, CFE_SB_DestinationD_t *dest); -int32 CFE_SB_ReadQueue(CFE_SB_PipeD_t *PipeDscPtr,CFE_ES_ResourceID_t TskId, - uint32 Time_Out,CFE_SB_BufferD_t **Message ); int32 CFE_SB_WriteQueue(CFE_SB_PipeD_t *pd,uint32 TskId, const CFE_SB_BufferD_t *bd,CFE_SB_MsgId_t MsgId ); -uint8 CFE_SB_GetPipeIdx(CFE_SB_PipeId_t PipeId); int32 CFE_SB_ReturnBufferToPool(CFE_SB_BufferD_t *bd); void CFE_SB_ProcessCmdPipePkt(CFE_SB_Buffer_t *SBBufPtr); void CFE_SB_ResetCounters(void); @@ -250,8 +245,6 @@ void CFE_SB_SetMsgSeqCnt(CFE_MSG_Message_t *MsgPtr,uint32 Count); char *CFE_SB_GetAppTskName(CFE_ES_ResourceID_t TaskId, char* FullName); CFE_SB_BufferD_t *CFE_SB_GetBufferFromPool(CFE_SB_MsgId_t MsgId, size_t Size); CFE_SB_BufferD_t *CFE_SB_GetBufferFromCaller(CFE_SB_MsgId_t MsgId, void *Address); -CFE_SB_PipeD_t *CFE_SB_GetPipePtr(CFE_SB_PipeId_t PipeId); -CFE_SB_PipeId_t CFE_SB_GetAvailPipeIdx(void); int32 CFE_SB_DeletePipeWithAppId(CFE_SB_PipeId_t PipeId,CFE_ES_ResourceID_t AppId); int32 CFE_SB_DeletePipeFull(CFE_SB_PipeId_t PipeId,CFE_ES_ResourceID_t AppId); int32 CFE_SB_SubscribeFull(CFE_SB_MsgId_t MsgId, @@ -277,12 +270,14 @@ int32 CFE_SB_SendPipeInfo(const char *Filename); int32 CFE_SB_SendMapInfo(const char *Filename); int32 CFE_SB_ZeroCopyReleaseDesc(CFE_SB_Buffer_t *Ptr2Release, CFE_SB_ZeroCopyHandle_t BufferHandle); int32 CFE_SB_ZeroCopyReleaseAppId(CFE_ES_ResourceID_t AppId); -int32 CFE_SB_DecrBufUseCnt(CFE_SB_BufferD_t *bd); +void CFE_SB_IncrBufUseCnt(CFE_SB_BufferD_t *bd); +void CFE_SB_DecrBufUseCnt(CFE_SB_BufferD_t *bd); int32 CFE_SB_ValidateMsgId(CFE_SB_MsgId_t MsgId); int32 CFE_SB_ValidatePipeId(CFE_SB_PipeId_t PipeId); void CFE_SB_IncrCmdCtr(int32 status); void CFE_SB_FileWriteByteCntErr(const char *Filename,uint32 Requested,uint32 Actual); void CFE_SB_SetSubscriptionReporting(uint32 state); +int32 CFE_SB_SendSubscriptionReport(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId, CFE_SB_Qos_t Quality); uint32 CFE_SB_RequestToSendEvent(CFE_ES_ResourceID_t TaskId, uint32 Bit); void CFE_SB_FinishSendEvent(CFE_ES_ResourceID_t TaskId, uint32 Bit); CFE_SB_DestinationD_t *CFE_SB_GetDestinationBlk(void); @@ -381,6 +376,104 @@ int32 CFE_SB_SendMapInfoCmd(const CFE_SB_SendMapInfoCmd_t *data); int32 CFE_SB_SendPrevSubsCmd(const CFE_SB_SendPrevSubsCmd_t *data); + +/** + * @brief Locate the Pipe table entry correlating with a given Pipe ID. + * + * This only returns a pointer to the table entry and does _not_ + * otherwise check/validate the entry. + * + * @param[in] PipeId the Pipe ID to locate + * @return pointer to Pipe Table entry for the given Pipe ID + */ +extern CFE_SB_PipeD_t* CFE_SB_LocatePipeDescByID(CFE_SB_PipeId_t PipeId); + + + +/** + * @brief Check if an Pipe descriptor is in use or free/empty + * + * This routine checks if the Pipe table entry is in use or if it is free + * + * As this dereferences fields within the descriptor, global data must be + * locked prior to invoking this function. + * + * @param[in] PipeDscPtr pointer to Pipe table entry + * @returns true if the entry is in use/configured, or false if it is free/empty + */ +static inline bool CFE_SB_PipeDescIsUsed(const CFE_SB_PipeD_t *PipeDscPtr) +{ + return CFE_ES_ResourceID_IsDefined(PipeDscPtr->PipeId); +} + +/** + * @brief Get the ID value from an Pipe table entry + * + * This routine converts the table entry back to an abstract ID. + * + * @param[in] PipeDscPtr pointer to Pipe table entry + * @returns PipeID of entry + */ +static inline CFE_SB_PipeId_t CFE_SB_PipeDescGetID(const CFE_SB_PipeD_t *PipeDscPtr) +{ + return PipeDscPtr->PipeId; +} + +/** + * @brief Marks an Pipe table entry as used (not free) + * + * This sets the internal field(s) within this entry, and marks + * it as being associated with the given Pipe ID. + * + * As this dereferences fields within the descriptor, global data must be + * locked prior to invoking this function. + * + * @param[in] PipeDscPtr pointer to Pipe table entry + * @param[in] PipeID the Pipe ID of this entry + */ +static inline void CFE_SB_PipeDescSetUsed(CFE_SB_PipeD_t *PipeDscPtr, CFE_SB_PipeId_t PipeID) +{ + PipeDscPtr->PipeId = PipeID; +} + +/** + * @brief Set an Pipe descriptor table entry free (not used) + * + * This clears the internal field(s) within this entry, and allows the + * memory to be re-used in the future. + * + * As this dereferences fields within the descriptor, global data must be + * locked prior to invoking this function. + * + * @param[in] PipeDscPtr pointer to Pipe table entry + */ +static inline void CFE_SB_PipeDescSetFree(CFE_SB_PipeD_t *PipeDscPtr) +{ + PipeDscPtr->PipeId = CFE_SB_INVALID_PIPE; +} + +/** + * @brief Check if an Pipe descriptor is a match for the given PipeID + * + * This routine confirms that the previously-located descriptor is valid + * and matches the expected Pipe ID. + * + * As this dereferences fields within the descriptor, global data must be + * locked prior to invoking this function. + * + * @param[in] PipeDscPtr pointer to Pipe table entry + * @param[in] PipeID expected Pipe ID + * @returns true if the entry matches the given Pipe ID + */ +static inline bool CFE_SB_PipeDescIsMatch(const CFE_SB_PipeD_t *PipeDscPtr, CFE_SB_PipeId_t PipeID) +{ + return (PipeDscPtr != NULL && CFE_ES_ResourceID_Equal(PipeDscPtr->PipeId, PipeID)); +} + +/* Availability check functions used in conjunction with CFE_ES_FindNextAvailableId() */ +bool CFE_SB_CheckPipeDescSlotUsed(CFE_SB_PipeId_t CheckId); + + /* * External variables private to the software bus module */ diff --git a/fsw/cfe-core/src/sb/cfe_sb_task.c b/fsw/cfe-core/src/sb/cfe_sb_task.c index 003f3c0f5..dc2cd0db9 100644 --- a/fsw/cfe-core/src/sb/cfe_sb_task.c +++ b/fsw/cfe-core/src/sb/cfe_sb_task.c @@ -233,10 +233,6 @@ int32 CFE_SB_AppInit(void){ CFE_SB_ValueToMsgId(CFE_SB_ALLSUBS_TLM_MID), sizeof(CFE_SB.PrevSubMsg)); - CFE_MSG_Init(&CFE_SB.SubRprtMsg.Hdr.Msg, - CFE_SB_ValueToMsgId(CFE_SB_ONESUB_TLM_MID), - sizeof(CFE_SB.SubRprtMsg)); - /* Populate the fixed fields in the HK Tlm Msg */ CFE_SB.HKTlmMsg.Payload.MemPoolHandle = CFE_SB.Mem.PoolHdl; @@ -569,9 +565,13 @@ int32 CFE_SB_DisableSubReportingCmd(const CFE_SB_DisableSubReportingCmd_t *data) */ int32 CFE_SB_SendHKTlmCmd(const CFE_MSG_CommandHeader_t *data) { + CFE_SB_LockSharedData(__FILE__, __LINE__); + CFE_SB.HKTlmMsg.Payload.MemInUse = CFE_SB.StatTlmMsg.Payload.MemInUse; CFE_SB.HKTlmMsg.Payload.UnmarkedMem = CFE_PLATFORM_SB_BUF_MEMORY_BYTES - CFE_SB.StatTlmMsg.Payload.PeakMemInUse; - + + CFE_SB_UnlockSharedData(__FILE__, __LINE__); + CFE_SB_TimeStampMsg(&CFE_SB.HKTlmMsg.Hdr.Msg); CFE_SB_TransmitMsg(&CFE_SB.HKTlmMsg.Hdr.Msg, true); @@ -627,49 +627,66 @@ void CFE_SB_ResetCounters(void){ int32 CFE_SB_EnableRouteCmd(const CFE_SB_EnableRouteCmd_t *data) { CFE_SB_MsgId_t MsgId; - CFE_SB_PipeId_t PipeId; + CFE_SB_PipeD_t *PipeDscPtr; CFE_SB_DestinationD_t *DestPtr; const CFE_SB_RouteCmd_Payload_t *CmdPtr; + uint16 PendingEventID; + PendingEventID = 0; CmdPtr = &data->Payload; MsgId = CmdPtr->MsgId; - PipeId = CmdPtr->Pipe; + + CFE_SB_LockSharedData(__func__,__LINE__); /* check cmd parameters */ + PipeDscPtr = CFE_SB_LocatePipeDescByID(CmdPtr->Pipe); if(!CFE_SB_IsValidMsgId(MsgId) || - (CFE_SB_ValidatePipeId(PipeId) != CFE_SUCCESS)) + !CFE_SB_PipeDescIsMatch(PipeDscPtr,CmdPtr->Pipe)) { - CFE_EVS_SendEvent(CFE_SB_ENBL_RTE3_EID,CFE_EVS_EventType_ERROR, - "Enbl Route Cmd:Invalid Param.Msg 0x%x,Pipe %d", - (unsigned int)CFE_SB_MsgIdToValue(MsgId),(int)PipeId); + PendingEventID = CFE_SB_ENBL_RTE3_EID; CFE_SB.HKTlmMsg.Payload.CommandErrorCounter++; - /* - * returning "success" here as there is no other recourse; - * the full extent of the error recovery has been done - */ - return CFE_SUCCESS; - }/* end if */ + } + else + { + DestPtr = CFE_SB_GetDestPtr(CFE_SBR_GetRouteId(MsgId), CmdPtr->Pipe); + if(DestPtr == NULL) + { + PendingEventID = CFE_SB_ENBL_RTE1_EID; + CFE_SB.HKTlmMsg.Payload.CommandErrorCounter++; + } + else + { + DestPtr->Active = CFE_SB_ACTIVE; + PendingEventID = CFE_SB_ENBL_RTE2_EID; + CFE_SB.HKTlmMsg.Payload.CommandCounter++; + } - DestPtr = CFE_SB_GetDestPtr(CFE_SBR_GetRouteId(MsgId), PipeId); - if(DestPtr == NULL){ - CFE_EVS_SendEvent(CFE_SB_ENBL_RTE1_EID,CFE_EVS_EventType_ERROR, - "Enbl Route Cmd:Route does not exist.Msg 0x%x,Pipe %d", - (unsigned int)CFE_SB_MsgIdToValue(MsgId),(int)PipeId); - CFE_SB.HKTlmMsg.Payload.CommandErrorCounter++; - /* - * returning "success" here as there is no other recourse; - * the full extent of the error recovery has been done - */ - return CFE_SUCCESS; - }/* end if */ + }/* end if */ - DestPtr->Active = CFE_SB_ACTIVE; - CFE_EVS_SendEvent(CFE_SB_ENBL_RTE2_EID,CFE_EVS_EventType_DEBUG, - "Enabling Route,Msg 0x%x,Pipe %d", - (unsigned int)CFE_SB_MsgIdToValue(MsgId),(int)PipeId); + CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_SB.HKTlmMsg.Payload.CommandCounter++; + switch(PendingEventID) + { + case CFE_SB_ENBL_RTE1_EID: + CFE_EVS_SendEvent(CFE_SB_ENBL_RTE1_EID,CFE_EVS_EventType_ERROR, + "Enbl Route Cmd:Route does not exist.Msg 0x%x,Pipe %lu", + (unsigned int)CFE_SB_MsgIdToValue(MsgId), + CFE_ES_ResourceID_ToInteger(CmdPtr->Pipe)); + break; + case CFE_SB_ENBL_RTE3_EID: + CFE_EVS_SendEvent(CFE_SB_ENBL_RTE3_EID,CFE_EVS_EventType_ERROR, + "Enbl Route Cmd:Invalid Param.Msg 0x%x,Pipe %lu", + (unsigned int)CFE_SB_MsgIdToValue(MsgId), + CFE_ES_ResourceID_ToInteger(CmdPtr->Pipe)); + break; + case CFE_SB_ENBL_RTE2_EID: + CFE_EVS_SendEvent(CFE_SB_ENBL_RTE2_EID,CFE_EVS_EventType_DEBUG, + "Enabling Route,Msg 0x%x,Pipe %lu", + (unsigned int)CFE_SB_MsgIdToValue(MsgId), + CFE_ES_ResourceID_ToInteger(CmdPtr->Pipe)); + break; + } return CFE_SUCCESS; }/* end CFE_SB_EnableRouteCmd */ @@ -692,48 +709,67 @@ int32 CFE_SB_EnableRouteCmd(const CFE_SB_EnableRouteCmd_t *data) int32 CFE_SB_DisableRouteCmd(const CFE_SB_DisableRouteCmd_t *data) { CFE_SB_MsgId_t MsgId; - CFE_SB_PipeId_t PipeId; + CFE_SB_PipeD_t *PipeDscPtr; CFE_SB_DestinationD_t *DestPtr; const CFE_SB_RouteCmd_Payload_t *CmdPtr; + uint16 PendingEventID; + PendingEventID = 0; CmdPtr = &data->Payload; MsgId = CmdPtr->MsgId; - PipeId = CmdPtr->Pipe; + + CFE_SB_LockSharedData(__func__,__LINE__); /* check cmd parameters */ + PipeDscPtr = CFE_SB_LocatePipeDescByID(CmdPtr->Pipe); if(!CFE_SB_IsValidMsgId(MsgId) || - (CFE_SB_ValidatePipeId(PipeId) != CFE_SUCCESS)){ - CFE_EVS_SendEvent(CFE_SB_DSBL_RTE3_EID,CFE_EVS_EventType_ERROR, - "Disable Route Cmd:Invalid Param.Msg 0x%x,Pipe %d", - (unsigned int)CFE_SB_MsgIdToValue(MsgId),(int)PipeId); + !CFE_SB_PipeDescIsMatch(PipeDscPtr,CmdPtr->Pipe)) + { + PendingEventID = CFE_SB_DSBL_RTE3_EID; CFE_SB.HKTlmMsg.Payload.CommandErrorCounter++; - /* - * returning "success" here as there is no other recourse; - * the full extent of the error recovery has been done - */ - return CFE_SUCCESS; - }/* end if */ + } + else + { + DestPtr = CFE_SB_GetDestPtr(CFE_SBR_GetRouteId(MsgId), CmdPtr->Pipe); + if(DestPtr == NULL) + { + PendingEventID = CFE_SB_DSBL_RTE1_EID; + CFE_SB.HKTlmMsg.Payload.CommandErrorCounter++; + } + else + { + DestPtr->Active = CFE_SB_INACTIVE; + PendingEventID = CFE_SB_DSBL_RTE2_EID; + CFE_SB.HKTlmMsg.Payload.CommandCounter++; + } - DestPtr = CFE_SB_GetDestPtr(CFE_SBR_GetRouteId(MsgId), PipeId); - if(DestPtr == NULL){ - CFE_EVS_SendEvent(CFE_SB_DSBL_RTE1_EID,CFE_EVS_EventType_ERROR, - "Disable Route Cmd:Route does not exist,Msg 0x%x,Pipe %d", - (unsigned int)CFE_SB_MsgIdToValue(MsgId),(int)PipeId); - CFE_SB.HKTlmMsg.Payload.CommandErrorCounter++; - /* - * returning "success" here as there is no other recourse; - * the full extent of the error recovery has been done - */ - return CFE_SUCCESS; - }/* end if */ + }/* end if */ - DestPtr->Active = CFE_SB_INACTIVE; + CFE_SB_UnlockSharedData(__func__,__LINE__); - CFE_EVS_SendEvent(CFE_SB_DSBL_RTE2_EID,CFE_EVS_EventType_DEBUG, - "Route Disabled,Msg 0x%x,Pipe %d", - (unsigned int)CFE_SB_MsgIdToValue(MsgId),(int)PipeId); - CFE_SB.HKTlmMsg.Payload.CommandCounter++; + + switch(PendingEventID) + { + case CFE_SB_DSBL_RTE1_EID: + CFE_EVS_SendEvent(CFE_SB_DSBL_RTE1_EID,CFE_EVS_EventType_ERROR, + "Disable Route Cmd:Route does not exist,Msg 0x%x,Pipe %lu", + (unsigned int)CFE_SB_MsgIdToValue(MsgId), + CFE_ES_ResourceID_ToInteger(CmdPtr->Pipe)); + break; + case CFE_SB_DSBL_RTE3_EID: + CFE_EVS_SendEvent(CFE_SB_DSBL_RTE3_EID,CFE_EVS_EventType_ERROR, + "Disable Route Cmd:Invalid Param.Msg 0x%x,Pipe %lu", + (unsigned int)CFE_SB_MsgIdToValue(MsgId), + CFE_ES_ResourceID_ToInteger(CmdPtr->Pipe)); + break; + case CFE_SB_DSBL_RTE2_EID: + CFE_EVS_SendEvent(CFE_SB_DSBL_RTE2_EID,CFE_EVS_EventType_DEBUG, + "Route Disabled,Msg 0x%x,Pipe %lu", + (unsigned int)CFE_SB_MsgIdToValue(MsgId), + CFE_ES_ResourceID_ToInteger(CmdPtr->Pipe)); + break; + } return CFE_SUCCESS; }/* end CFE_SB_DisableRouteCmd */ @@ -753,6 +789,45 @@ int32 CFE_SB_DisableRouteCmd(const CFE_SB_DisableRouteCmd_t *data) */ int32 CFE_SB_SendStatsCmd(const CFE_SB_SendSbStatsCmd_t *data) { + uint32 PipeDscCount; + uint32 PipeStatCount; + CFE_SB_PipeD_t *PipeDscPtr; + CFE_SB_PipeDepthStats_t *PipeStatPtr; + + CFE_SB_LockSharedData(__FILE__, __LINE__); + + /* Collect data on pipes */ + PipeDscCount = CFE_PLATFORM_SB_MAX_PIPES; + PipeStatCount = CFE_MISSION_SB_MAX_PIPES; + PipeDscPtr = CFE_SB.PipeTbl; + PipeStatPtr = CFE_SB.StatTlmMsg.Payload.PipeDepthStats; + + while (PipeDscCount > 0 && PipeStatCount > 0) + { + if (CFE_SB_PipeDescIsUsed(PipeDscPtr)) + { + PipeStatPtr->PipeId = PipeDscPtr->PipeId; + PipeStatPtr->InUse = PipeDscPtr->CurrentDepth; + PipeStatPtr->PeakInUse = PipeDscPtr->PeakDepth; + PipeStatPtr->Depth = PipeDscPtr->QueueDepth; + + ++PipeStatPtr; + --PipeStatCount; + } + + --PipeDscCount; + ++PipeDscPtr; + } + + CFE_SB_UnlockSharedData(__FILE__, __LINE__); + + while (PipeStatCount > 0) + { + memset(PipeStatPtr, 0, sizeof(*PipeStatPtr)); + + ++PipeStatPtr; + --PipeStatCount; + } CFE_SB_TimeStampMsg(&CFE_SB.StatTlmMsg.Hdr.Msg); CFE_SB_TransmitMsg(&CFE_SB.StatTlmMsg.Hdr.Msg, true); @@ -861,57 +936,129 @@ int32 CFE_SB_SendMapInfoCmd(const CFE_SB_SendMapInfoCmd_t *data) */ void CFE_SB_WriteRouteToFile(CFE_SBR_RouteId_t RouteId, void *ArgPtr) { + struct RouteInfo + { + CFE_SB_PipeId_t PipeId; + uint8 Active; + uint16 DestCnt; + }; + CFE_SB_FileWriteCallback_t *args; CFE_SB_DestinationD_t *destptr; CFE_SB_PipeD_t *pipedptr; int32 status; CFE_SB_RoutingFileEntry_t entry; + struct RouteInfo RouteInfo[CFE_PLATFORM_SB_MAX_DEST_PER_PKT]; + struct RouteInfo *RouteInfoPtr; + uint32 NumDest; /* Cast arguments for local use */ args = (CFE_SB_FileWriteCallback_t *)ArgPtr; + NumDest = 0; + + /* Data must be locked to snapshot the route info */ + CFE_SB_LockSharedData(__FILE__, __LINE__); + destptr = CFE_SBR_GetDestListHeadPtr(RouteId); + entry.MsgId = CFE_SBR_GetMsgId(RouteId); + RouteInfoPtr = RouteInfo; - while((destptr != NULL) && (args->Status != CFE_SB_FILE_IO_ERR)) + while((destptr != NULL) && NumDest < CFE_PLATFORM_SB_MAX_DEST_PER_PKT) { - - pipedptr = CFE_SB_GetPipePtr(destptr->PipeId); + pipedptr = CFE_SB_LocatePipeDescByID(destptr->PipeId); /* If invalid id, continue on to next entry */ - if (pipedptr != NULL) + if (CFE_SB_PipeDescIsMatch(pipedptr,destptr->PipeId)) { + RouteInfoPtr->PipeId = destptr->PipeId; + RouteInfoPtr->Active = destptr->Active; + RouteInfoPtr->DestCnt = destptr->DestCnt; + ++RouteInfoPtr; + ++NumDest; + } - entry.MsgId = CFE_SBR_GetMsgId(RouteId); - entry.PipeId = destptr->PipeId; - entry.State = destptr->Active; - entry.MsgCnt = destptr->DestCnt; + destptr = destptr->Next; + } - entry.AppName[0] = 0; - /* - * NOTE: as long as CFE_ES_GetAppName() returns success, then it - * guarantees null termination of the output. Return code is not - * checked here (bad) but in case of error it does not seem to touch - * the buffer, therefore the initialization above will protect for now - */ - CFE_ES_GetAppName(entry.AppName, pipedptr->AppId, sizeof(entry.AppName)); - CFE_SB_GetPipeName(entry.PipeName, sizeof(entry.PipeName), entry.PipeId); + CFE_SB_UnlockSharedData(__FILE__, __LINE__); - status = OS_write (args->Fd, &entry, sizeof(CFE_SB_RoutingFileEntry_t)); - if(status != sizeof(CFE_SB_RoutingFileEntry_t)) - { - CFE_SB_FileWriteByteCntErr(args->Filename, sizeof(CFE_SB_RoutingFileEntry_t), status); - OS_close(args->Fd); - args->Status = CFE_SB_FILE_IO_ERR; - } + RouteInfoPtr = RouteInfo; + while (NumDest > 0) + { + entry.PipeId = RouteInfoPtr->PipeId; + entry.State = RouteInfoPtr->Active; + entry.MsgCnt = RouteInfoPtr->DestCnt; + + entry.AppName[0] = 0; - args->FileSize += status; - args->EntryCount++; + /* + * NOTE: as long as CFE_ES_GetAppName() returns success, then it + * guarantees null termination of the output. Return code is not + * checked here (bad) but in case of error it does not seem to touch + * the buffer, therefore the initialization above will protect for now + */ + CFE_ES_GetAppName(entry.AppName, pipedptr->AppId, sizeof(entry.AppName)); + CFE_SB_GetPipeName(entry.PipeName, sizeof(entry.PipeName), entry.PipeId); + + status = OS_write (args->Fd, &entry, sizeof(CFE_SB_RoutingFileEntry_t)); + if(status != sizeof(CFE_SB_RoutingFileEntry_t)) + { + CFE_SB_FileWriteByteCntErr(args->Filename, sizeof(CFE_SB_RoutingFileEntry_t), status); + OS_close(args->Fd); + args->Status = CFE_SB_FILE_IO_ERR; } - destptr = destptr->Next; + args->FileSize += status; + args->EntryCount++; + + ++RouteInfoPtr; + --NumDest; } } +/****************************************************************************** +** Function: CFE_SB_SendSubscriptionReport() +** +** Purpose: +** SB internal function to generate the "ONESUB_TLM" message after a subscription. +** No-op when subscription reporting is disabled. +** +** Arguments: +** Payload of notification message - MsgId, PipeId, QOS +** +** Return: +** CFE_SUCCESS or error code +*/ +int32 CFE_SB_SendSubscriptionReport(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId, CFE_SB_Qos_t Quality) +{ + CFE_SB_SingleSubscriptionTlm_t SubRptMsg; + int32 Status; + + Status = CFE_SUCCESS; + + if (CFE_SB.SubscriptionReporting == CFE_SB_ENABLE) + { + CFE_MSG_Init(&SubRptMsg.Hdr.Msg, + CFE_SB_ValueToMsgId(CFE_SB_ONESUB_TLM_MID), + sizeof(SubRptMsg)); + + SubRptMsg.Payload.MsgId = MsgId; + SubRptMsg.Payload.Pipe = PipeId; + SubRptMsg.Payload.Qos = Quality; + SubRptMsg.Payload.SubType = CFE_SB_SUBSCRIPTION; + + Status = CFE_SB_TransmitMsg(&SubRptMsg.Hdr.Msg, true); + CFE_EVS_SendEventWithAppID(CFE_SB_SUBSCRIPTION_RPT_EID,CFE_EVS_EventType_DEBUG,CFE_SB.AppId, + "Sending Subscription Report Msg=0x%x,Pipe=%lu,Stat=0x%x", + (unsigned int)CFE_SB_MsgIdToValue(MsgId), + CFE_ES_ResourceID_ToInteger(PipeId),(unsigned int)Status); + } + + return Status; +} + + /****************************************************************************** ** Function: CFE_SB_SendRoutingInfo() ** @@ -993,6 +1140,8 @@ int32 CFE_SB_SendPipeInfo(const char *Filename) uint32 FileSize = 0; uint32 EntryCount = 0; CFE_FS_Header_t FileHdr; + CFE_SB_PipeD_t *PipeDscPtr; + CFE_SB_PipeD_t entry; /* NOTE: Should be separate/dedicated type */ Status = OS_OpenCreate(&fd, Filename, OS_FILE_FLAG_CREATE | OS_FILE_FLAG_TRUNCATE, OS_WRITE_ONLY); @@ -1015,13 +1164,21 @@ int32 CFE_SB_SendPipeInfo(const char *Filename) FileSize = Status; - /* loop through the pipe table */ - for(i=0;iStatus != CFE_SB_FILE_IO_ERR) { + CFE_SB_LockSharedData(__FILE__,__LINE__); entry.MsgId = CFE_SBR_GetMsgId(RouteId); entry.Index = CFE_SBR_RouteIdToValue(RouteId); + CFE_SB_UnlockSharedData(__FILE__,__LINE__); status = OS_write (args->Fd, &entry, sizeof(CFE_SB_MsgMapFileEntry_t)); if(status != sizeof(CFE_SB_MsgMapFileEntry_t)) @@ -1295,8 +1460,3 @@ void CFE_SB_SetSubscriptionReporting(uint32 state){ CFE_SB.SubscriptionReporting = state; }/* end CFE_SB_SetSubscriptionReporting */ - - - - - diff --git a/fsw/cfe-core/src/time/cfe_time_tone.c b/fsw/cfe-core/src/time/cfe_time_tone.c index 40b86f1b9..0cc067723 100644 --- a/fsw/cfe-core/src/time/cfe_time_tone.c +++ b/fsw/cfe-core/src/time/cfe_time_tone.c @@ -1459,7 +1459,7 @@ void CFE_TIME_Local1HzTask(void) /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -void CFE_TIME_NotifyTimeSynchApps(void) +void CFE_TIME_NotifyTimeSynchApps(void) { uint32 i = 0; CFE_TIME_SynchCallbackPtr_t Func; diff --git a/fsw/cfe-core/unit-test/sb_UT.c b/fsw/cfe-core/unit-test/sb_UT.c index e7522dd6d..06624f099 100644 --- a/fsw/cfe-core/unit-test/sb_UT.c +++ b/fsw/cfe-core/unit-test/sb_UT.c @@ -112,6 +112,12 @@ const CFE_SB_MsgId_t SB_UT_ALTERNATE_INVALID_MID = CFE_SB_MSGID_WRAP_VALUE(CFE_P const CFE_SB_MsgId_t SB_UT_BARE_CMD_MID3 = CFE_SB_MSGID_WRAP_VALUE(0x1003); const CFE_SB_MsgId_t SB_UT_BARE_TLM_MID3 = CFE_SB_MSGID_WRAP_VALUE(0x0003); +const CFE_SB_PipeId_t SB_UT_PIPEID_0 = { CFE_SB_PIPEID_BASE + 0 }; +const CFE_SB_PipeId_t SB_UT_PIPEID_1 = { CFE_SB_PIPEID_BASE + 1 }; +const CFE_SB_PipeId_t SB_UT_PIPEID_2 = { CFE_SB_PIPEID_BASE + 2 }; +const CFE_SB_PipeId_t SB_UT_PIPEID_3 = { CFE_SB_PIPEID_BASE + 3 }; +const CFE_SB_PipeId_t SB_UT_ALTERNATE_INVALID_PIPEID = { 0xDEADBEEF }; + /* * Helper function to "corrupt" a resource ID value in a consistent/predicatble way, * which can also be un-done easily. @@ -227,7 +233,7 @@ void Test_SB_AppInit_EVSSendEvtFail(void) UT_SetDeferredRetcode(UT_KEY(CFE_EVS_SendEvent), 1, ForcedRtnVal); ASSERT_EQ(CFE_SB_AppInit(), ForcedRtnVal); - EVTCNT(7); + EVTCNT(4); TEARDOWN(CFE_SB_DeletePipe(CFE_SB.CmdPipe)); @@ -255,8 +261,6 @@ void Test_SB_AppInit_CrPipeFail(void) */ void Test_SB_AppInit_Sub1Fail(void) { - CFE_SB_PipeId_t PipeId = 0; - UT_SetDeferredRetcode(UT_KEY(CFE_ES_GetPoolBuf), 1, -1); ASSERT_EQ(CFE_SB_AppInit(), CFE_SB_BUF_ALOC_ERR); @@ -264,7 +268,7 @@ void Test_SB_AppInit_Sub1Fail(void) EVTSENT(CFE_SB_DEST_BLK_ERR_EID); - TEARDOWN(CFE_SB_DeletePipe(PipeId)); + TEARDOWN(CFE_SB_DeletePipe(CFE_SB.CmdPipe)); } /* end Test_SB_AppInit_Sub1Fail */ @@ -273,16 +277,14 @@ void Test_SB_AppInit_Sub1Fail(void) */ void Test_SB_AppInit_Sub2Fail(void) { - CFE_SB_PipeId_t PipeId = 0; - UT_SetDeferredRetcode(UT_KEY(CFE_ES_GetPoolBuf), 2, -1); ASSERT_EQ(CFE_SB_AppInit(), CFE_SB_BUF_ALOC_ERR); - EVTCNT(5); + EVTCNT(4); EVTSENT(CFE_SB_DEST_BLK_ERR_EID); - TEARDOWN(CFE_SB_DeletePipe(PipeId)); + TEARDOWN(CFE_SB_DeletePipe(CFE_SB.CmdPipe)); } /* end Test_SB_AppInit_Sub2Fail */ @@ -291,16 +293,15 @@ void Test_SB_AppInit_Sub2Fail(void) */ void Test_SB_AppInit_GetPoolFail(void) { - CFE_SB_PipeId_t PipeId = 0; int32 ForcedRtnVal = -1; UT_SetDeferredRetcode(UT_KEY(CFE_ES_GetPoolBuf), 4, ForcedRtnVal); ASSERT_EQ(CFE_SB_AppInit(), ForcedRtnVal); - EVTCNT(7); + EVTCNT(4); - TEARDOWN(CFE_SB_DeletePipe(PipeId)); + TEARDOWN(CFE_SB_DeletePipe(CFE_SB.CmdPipe)); } /* end Test_SB_AppInit_GetPoolFail */ @@ -309,16 +310,15 @@ void Test_SB_AppInit_GetPoolFail(void) */ void Test_SB_AppInit_PutPoolFail(void) { - CFE_SB_PipeId_t PipeId = 0; int32 ForcedRtnVal = -1; UT_SetDeferredRetcode(UT_KEY(CFE_ES_PutPoolBuf), 1, ForcedRtnVal); ASSERT_EQ(CFE_SB_AppInit(), ForcedRtnVal); - EVTCNT(7); + EVTCNT(4); - TEARDOWN(CFE_SB_DeletePipe(PipeId)); + TEARDOWN(CFE_SB_DeletePipe(CFE_SB.CmdPipe)); } /* end Test_SB_AppInit_PutPoolFail */ @@ -336,18 +336,16 @@ void Test_SB_MainRoutine(void) */ void Test_SB_Main_RcvErr(void) { - CFE_SB_PipeId_t PipeId = 0; - UT_SetDeferredRetcode(UT_KEY(OS_QueueGet), 1, -1); CFE_SB_TaskMain(); - EVTCNT(10); + EVTCNT(6); EVTSENT(CFE_SB_INIT_EID); EVTSENT(CFE_SB_Q_RD_ERR_EID); - TEARDOWN(CFE_SB_DeletePipe(PipeId)); + TEARDOWN(CFE_SB_DeletePipe(CFE_SB.CmdPipe)); } /* end Test_SB_Main_RcvErr */ @@ -356,14 +354,12 @@ void Test_SB_Main_RcvErr(void) */ void Test_SB_Main_InitErr(void) { - CFE_SB_PipeId_t PipeId = 0; - UT_SetDeferredRetcode(UT_KEY(CFE_ES_PutPoolBuf), 1, -1); CFE_SB_TaskMain(); - EVTCNT(7); + EVTCNT(4); - TEARDOWN(CFE_SB_DeletePipe(PipeId)); + TEARDOWN(CFE_SB_DeletePipe(CFE_SB.CmdPipe)); } /* end Test_SB_Main_InitErr */ @@ -507,7 +503,6 @@ void Test_SB_Cmds_RoutingInfoDef(void) CFE_SB_Buffer_t SBBuf; CFE_SB_SendRoutingInfoCmd_t Cmd; } SendRoutingInfo; - CFE_SB_PipeId_t PipeId = 0; CFE_MSG_FcnCode_t FcnCode = CFE_SB_SEND_ROUTING_INFO_CC; CFE_SB_MsgId_t MsgId = CFE_SB_ValueToMsgId(CFE_SB_CMD_MID); CFE_MSG_Size_t Size = sizeof(SendRoutingInfo.Cmd); @@ -522,7 +517,7 @@ void Test_SB_Cmds_RoutingInfoDef(void) CFE_SB_ProcessCmdPipePkt(&SendRoutingInfo.SBBuf); - EVTCNT(12); + EVTCNT(9); EVTSENT(CFE_SB_INIT_EID); @@ -532,7 +527,7 @@ void Test_SB_Cmds_RoutingInfoDef(void) EVTSENT(CFE_SB_SND_RTG_EID); - TEARDOWN(CFE_SB_DeletePipe(PipeId)); + TEARDOWN(CFE_SB_DeletePipe(CFE_SB.CmdPipe)); } /* end Test_SB_Cmds_RoutingInfoDef */ @@ -616,8 +611,6 @@ void Test_SB_Cmds_RoutingInfoHdrFail(void) */ void Test_SB_Cmds_RoutingInfoWriteFail(void) { - CFE_SB_PipeId_t PipeId = 0; - /* Make some routing info by calling CFE_SB_AppInit */ SETUP(CFE_SB_AppInit()); @@ -625,7 +618,7 @@ void Test_SB_Cmds_RoutingInfoWriteFail(void) ASSERT_EQ(CFE_SB_SendRtgInfo("RoutingTstFile"), CFE_SB_FILE_IO_ERR); - EVTCNT(11); + EVTCNT(9); EVTSENT(CFE_SB_PIPE_ADDED_EID); @@ -635,7 +628,7 @@ void Test_SB_Cmds_RoutingInfoWriteFail(void) EVTSENT(CFE_SB_FILEWRITE_ERR_EID); - TEARDOWN(CFE_SB_DeletePipe(PipeId)); + TEARDOWN(CFE_SB_DeletePipe(CFE_SB.CmdPipe)); } /* end Test_SB_Cmds_RoutingInfoWriteFail */ @@ -808,7 +801,7 @@ void Test_SB_Cmds_MapInfoDef(void) CFE_SB_ProcessCmdPipePkt(&SendMapInfo.SBBuf); - EVTCNT(18); + EVTCNT(11); EVTSENT(CFE_SB_SND_RTG_EID); @@ -910,7 +903,7 @@ void Test_SB_Cmds_MapInfoWriteFail(void) ASSERT_EQ(CFE_SB_SendMapInfo("MapTstFile"), CFE_SB_FILE_IO_ERR); - EVTCNT(18); + EVTCNT(11); EVTSENT(CFE_SB_FILEWRITE_ERR_EID); @@ -953,7 +946,7 @@ void Test_SB_Cmds_EnRouteValParam(void) CFE_SB_ProcessCmdPipePkt(&EnableRoute.SBBuf); - EVTCNT(4); + EVTCNT(3); EVTSENT(CFE_SB_PIPE_ADDED_EID); @@ -995,7 +988,7 @@ void Test_SB_Cmds_EnRouteNonExist(void) CFE_SB_ProcessCmdPipePkt(&EnableRoute.SBBuf); - EVTCNT(5); + EVTCNT(4); EVTSENT(CFE_SB_PIPE_ADDED_EID); EVTSENT(CFE_SB_SUBSCRIPTION_RCVD_EID); @@ -1025,7 +1018,7 @@ void Test_SB_Cmds_EnRouteInvParam(void) UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); EnableRoute.Cmd.Payload.MsgId = SB_UT_LAST_VALID_MID; - EnableRoute.Cmd.Payload.Pipe = 3; + EnableRoute.Cmd.Payload.Pipe = SB_UT_PIPEID_3; CFE_SB_ProcessCmdPipePkt(&EnableRoute.SBBuf); @@ -1054,7 +1047,7 @@ void Test_SB_Cmds_EnRouteInvParam2(void) UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); EnableRoute.Cmd.Payload.MsgId = CFE_SB_INVALID_MSG_ID; - EnableRoute.Cmd.Payload.Pipe = 3; + EnableRoute.Cmd.Payload.Pipe = SB_UT_PIPEID_3; CFE_SB_ProcessCmdPipePkt(&EnableRoute.SBBuf); @@ -1084,7 +1077,7 @@ void Test_SB_Cmds_EnRouteInvParam3(void) UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); EnableRoute.Cmd.Payload.MsgId = SB_UT_ALTERNATE_INVALID_MID; - EnableRoute.Cmd.Payload.Pipe = 0; + EnableRoute.Cmd.Payload.Pipe = SB_UT_PIPEID_0; CFE_SB_ProcessCmdPipePkt(&EnableRoute.SBBuf); @@ -1122,7 +1115,7 @@ void Test_SB_Cmds_DisRouteValParam(void) CFE_SB_ProcessCmdPipePkt(&DisableRoute.SBBuf); - EVTCNT(4); + EVTCNT(3); EVTSENT(CFE_SB_PIPE_ADDED_EID); @@ -1163,7 +1156,7 @@ void Test_SB_Cmds_DisRouteNonExist(void) CFE_SB_ProcessCmdPipePkt(&DisableRoute.SBBuf); - EVTCNT(5); + EVTCNT(4); EVTSENT(CFE_SB_PIPE_ADDED_EID); EVTSENT(CFE_SB_SUBSCRIPTION_RCVD_EID); @@ -1193,7 +1186,7 @@ void Test_SB_Cmds_DisRouteInvParam(void) UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); DisableRoute.Cmd.Payload.MsgId = SB_UT_LAST_VALID_MID; - DisableRoute.Cmd.Payload.Pipe = 3; + DisableRoute.Cmd.Payload.Pipe = SB_UT_PIPEID_3; CFE_SB_ProcessCmdPipePkt(&DisableRoute.SBBuf); @@ -1222,7 +1215,7 @@ void Test_SB_Cmds_DisRouteInvParam2(void) UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); DisableRoute.Cmd.Payload.MsgId = CFE_SB_INVALID_MSG_ID; - DisableRoute.Cmd.Payload.Pipe = 3; + DisableRoute.Cmd.Payload.Pipe = SB_UT_PIPEID_3; CFE_SB_ProcessCmdPipePkt(&DisableRoute.SBBuf); @@ -1252,7 +1245,7 @@ void Test_SB_Cmds_DisRouteInvParam3(void) UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); DisableRoute.Cmd.Payload.MsgId = SB_UT_ALTERNATE_INVALID_MID; - DisableRoute.Cmd.Payload.Pipe = 0; + DisableRoute.Cmd.Payload.Pipe = SB_UT_PIPEID_0; CFE_SB_ProcessCmdPipePkt(&DisableRoute.SBBuf); @@ -1332,7 +1325,7 @@ void Test_SB_Cmds_SendPrevSubs(void) * */ if (i != CFE_SB_ALLSUBS_TLM_MID) { - NumEvts += 2; + NumEvts += 1; SETUP(CFE_SB_Subscribe(CFE_SB_ValueToMsgId(i), PipeId1)); } } @@ -1358,7 +1351,7 @@ void Test_SB_Cmds_SendPrevSubs(void) CFE_SB_ProcessCmdPipePkt(&SendPrevSubs.SBBuf); - NumEvts += 8; /* +2 for the subscribe, +6 for the SEND_PREV_SUBS_CC */ + NumEvts += 7; /* +1 for the subscribe, +6 for the SEND_PREV_SUBS_CC */ /* Event count is only exact if there were no collisions */ if (UT_EventIsInHistory(CFE_SB_HASHCOLLISION_EID)) @@ -1376,7 +1369,7 @@ void Test_SB_Cmds_SendPrevSubs(void) for (; i < CFE_SB_SUB_ENTRIES_PER_PKT * 3; i++) { SETUP(CFE_SB_Subscribe(CFE_SB_ValueToMsgId(i), PipeId1)); - NumEvts += 2; + NumEvts += 1; } SETUP(CFE_SB_SubscribeLocal(MsgId, PipeId2, MsgLim)); @@ -1685,6 +1678,7 @@ void Test_CreatePipe_MaxPipes(void) /* Create maximum number of pipes + 1. Only one 'create pipe' failure * expected */ + UT_SetDeferredRetcode(UT_KEY(CFE_ES_ResourceID_ToIndex), 1+CFE_PLATFORM_SB_MAX_PIPES, -1); for (i = 0; i < (CFE_PLATFORM_SB_MAX_PIPES + 1); i++) { snprintf(PipeName, OS_MAX_API_NAME, "TestPipe%ld", (long) i); @@ -1714,8 +1708,8 @@ void Test_CreatePipe_MaxPipes(void) */ void Test_CreatePipe_SamePipeName(void) { - CFE_SB_PipeId_t FirstPipeId = -1; - CFE_SB_PipeId_t PipeId = -1; + CFE_SB_PipeId_t FirstPipeId = CFE_SB_INVALID_PIPE; + CFE_SB_PipeId_t PipeId = CFE_SB_INVALID_PIPE; uint16 PipeDepth = 1; char PipeName[] = "Test_CFE_SB"; @@ -1731,7 +1725,7 @@ void Test_CreatePipe_SamePipeName(void) /* Second call to CFE_SB_CreatePipe with same PipeName should fail */ ASSERT_EQ(CFE_SB_CreatePipe(&PipeId, PipeDepth, PipeName), CFE_SB_PIPE_CR_ERR); - ASSERT_EQ(PipeId, FirstPipeId); + ASSERT_TRUE(CFE_ES_ResourceID_Equal(PipeId, FirstPipeId)); EVTCNT(2); @@ -1791,7 +1785,7 @@ void Test_DeletePipe_WithSubs(void) SETUP(CFE_SB_Subscribe(MsgId3, PipedId)); ASSERT(CFE_SB_DeletePipe(PipedId)); - EVTCNT(10); + EVTCNT(6); EVTSENT(CFE_SB_PIPE_ADDED_EID); EVTSENT(CFE_SB_PIPE_DELETED_EID); @@ -1803,7 +1797,7 @@ void Test_DeletePipe_WithSubs(void) */ void Test_DeletePipe_InvalidPipeId(void) { - CFE_SB_PipeId_t PipeId = 30; + CFE_SB_PipeId_t PipeId = SB_UT_ALTERNATE_INVALID_PIPEID; ASSERT_EQ(CFE_SB_DeletePipe(PipeId), CFE_SB_BAD_ARGUMENT); @@ -1819,16 +1813,18 @@ void Test_DeletePipe_InvalidPipeId(void) void Test_DeletePipe_InvalidPipeOwner(void) { CFE_SB_PipeId_t PipedId; + CFE_SB_PipeD_t *PipeDscPtr; CFE_ES_ResourceID_t RealOwner; uint16 PipeDepth = 10; SETUP(CFE_SB_CreatePipe(&PipedId, PipeDepth, "TestPipe")); /* Change owner of pipe through memory corruption */ - RealOwner = CFE_SB.PipeTbl[PipedId].AppId; + PipeDscPtr = CFE_SB_LocatePipeDescByID(PipedId); + RealOwner = PipeDscPtr->AppId; /* Choose a value that is sure not to be owner */ - CFE_SB.PipeTbl[PipedId].AppId = UT_SB_ResourceID_Modify(RealOwner, 1); + PipeDscPtr->AppId = UT_SB_ResourceID_Modify(RealOwner, 1); ASSERT_EQ(CFE_SB_DeletePipe(PipedId), CFE_SB_BAD_ARGUMENT); EVTCNT(2); @@ -1836,7 +1832,7 @@ void Test_DeletePipe_InvalidPipeOwner(void) EVTSENT(CFE_SB_DEL_PIPE_ERR2_EID); /* Restore owner id and delete pipe since test is complete */ - CFE_SB.PipeTbl[PipedId].AppId = RealOwner; + PipeDscPtr->AppId = RealOwner; TEARDOWN(CFE_SB_DeletePipe(PipedId)); } /* end Test_DeletePipe_InvalidPipeId */ @@ -1859,7 +1855,7 @@ void Test_DeletePipe_WithAppid(void) ASSERT(CFE_SB_DeletePipeWithAppId(PipedId, AppId)); - EVTCNT(10); + EVTCNT(6); } /* end Test_DeletePipe_WithAppid */ @@ -1891,10 +1887,15 @@ void Test_GetPipeName_API(void) */ void Test_GetPipeName_NullPtr(void) { - ASSERT_EQ(CFE_SB_GetPipeName(NULL, OS_MAX_API_NAME, 0), CFE_SB_BAD_ARGUMENT); + CFE_SB_PipeId_t PipeId; + + SETUP(CFE_SB_CreatePipe(&PipeId, 4, "TestPipe")); + ASSERT_EQ(CFE_SB_GetPipeName(NULL, OS_MAX_API_NAME, PipeId), CFE_SB_BAD_ARGUMENT); EVTSENT(CFE_SB_GETPIPENAME_NULL_PTR_EID); + TEARDOWN(CFE_SB_DeletePipe(PipeId)); + } /* end Test_GetPipeName_NullPtr */ /* @@ -1903,13 +1904,17 @@ void Test_GetPipeName_NullPtr(void) void Test_GetPipeName_InvalidId(void) { char PipeName[OS_MAX_API_NAME]; + CFE_SB_PipeId_t PipeId; - UT_SetDeferredRetcode(UT_KEY(OS_QueueGetInfo), 1, OS_ERROR); + SETUP(CFE_SB_CreatePipe(&PipeId, 4, "TestPipe")); - ASSERT_EQ(CFE_SB_GetPipeName(PipeName, OS_MAX_API_NAME, 0), CFE_SB_BAD_ARGUMENT); + UT_SetDeferredRetcode(UT_KEY(OS_GetResourceName), 1, OS_ERROR); + ASSERT_EQ(CFE_SB_GetPipeName(PipeName, OS_MAX_API_NAME, PipeId), CFE_SB_BAD_ARGUMENT); EVTSENT(CFE_SB_GETPIPENAME_ID_ERR_EID); + TEARDOWN(CFE_SB_DeletePipe(PipeId)); + } /* end Test_GetPipeName_InvalidId */ /* @@ -1918,7 +1923,7 @@ void Test_GetPipeName_InvalidId(void) void Test_GetPipeName(void) { char PipeName[OS_MAX_API_NAME]; - CFE_SB_PipeId_t PipeId = 0; + CFE_SB_PipeId_t PipeId = SB_UT_PIPEID_0; OS_queue_prop_t queue_info = { "TestPipe1" @@ -1954,7 +1959,7 @@ void Test_GetPipeIdByName_API(void) */ void Test_GetPipeIdByName_NullPtrs(void) { - CFE_SB_PipeId_t PipeIDOut = 0; + CFE_SB_PipeId_t PipeIDOut; ASSERT_EQ(CFE_SB_GetPipeIdByName(&PipeIDOut, NULL), CFE_SB_BAD_ARGUMENT); @@ -1971,8 +1976,9 @@ void Test_GetPipeIdByName_NullPtrs(void) */ void Test_GetPipeIdByName_InvalidName(void) { - CFE_SB_PipeId_t PipeIdOut = 0; + CFE_SB_PipeId_t PipeIdOut; + UT_SetDeferredRetcode(UT_KEY(OS_QueueGetIdByName), 1, OS_ERR_NAME_NOT_FOUND); ASSERT_EQ(CFE_SB_GetPipeIdByName(&PipeIdOut, "invalid"), CFE_SB_BAD_ARGUMENT); EVTSENT(CFE_SB_GETPIPEIDBYNAME_NAME_ERR_EID); @@ -1984,7 +1990,8 @@ void Test_GetPipeIdByName_InvalidName(void) */ void Test_GetPipeIdByName(void) { - CFE_SB_PipeId_t PipeId = 0, PipeIdOut = 0; + CFE_SB_PipeId_t PipeId = SB_UT_PIPEID_0; + CFE_SB_PipeId_t PipeIdOut; SETUP(CFE_SB_CreatePipe(&PipeId, 4, "TestPipe1")); @@ -2007,7 +2014,7 @@ void Test_GetPipeIdByName(void) */ void Test_SetPipeOpts_BadID(void) { - ASSERT_EQ(CFE_SB_SetPipeOpts(CFE_PLATFORM_SB_MAX_PIPES, 0), CFE_SB_BAD_ARGUMENT); + ASSERT_EQ(CFE_SB_SetPipeOpts(SB_UT_ALTERNATE_INVALID_PIPEID, 0), CFE_SB_BAD_ARGUMENT); EVTSENT(CFE_SB_SETPIPEOPTS_ID_ERR_EID); @@ -2018,19 +2025,20 @@ void Test_SetPipeOpts_BadID(void) */ void Test_SetPipeOpts_NotOwner(void) { - CFE_SB_PipeId_t PipeID = 0; - uint8 PipeTblIdx = 0; + CFE_SB_PipeId_t PipeID; + CFE_SB_PipeD_t *PipeDscPtr; CFE_ES_ResourceID_t OrigOwner; SETUP(CFE_SB_CreatePipe(&PipeID, 4, "TestPipe1")); - PipeTblIdx = CFE_SB_GetPipeIdx(PipeID); + PipeDscPtr = CFE_SB_LocatePipeDescByID(PipeID); + + OrigOwner = PipeDscPtr->AppId; + PipeDscPtr->AppId = UT_SB_ResourceID_Modify(OrigOwner, 1); - OrigOwner = CFE_SB.PipeTbl[PipeTblIdx].AppId; - CFE_SB.PipeTbl[PipeTblIdx].AppId = UT_SB_ResourceID_Modify(OrigOwner, 1); ASSERT_EQ(CFE_SB_SetPipeOpts(PipeID, 0), CFE_SB_BAD_ARGUMENT); - CFE_SB.PipeTbl[PipeTblIdx].AppId = OrigOwner; + PipeDscPtr->AppId = OrigOwner; EVTSENT(CFE_SB_SETPIPEOPTS_OWNER_ERR_EID); @@ -2043,7 +2051,7 @@ void Test_SetPipeOpts_NotOwner(void) */ void Test_SetPipeOpts(void) { - CFE_SB_PipeId_t PipeID = 0; + CFE_SB_PipeId_t PipeID; SETUP(CFE_SB_CreatePipe(&PipeID, 4, "TestPipe1")); @@ -2062,7 +2070,7 @@ void Test_GetPipeOpts_BadID(void) { uint8 Opts = 0; - ASSERT_EQ(CFE_SB_GetPipeOpts(CFE_PLATFORM_SB_MAX_PIPES, &Opts), CFE_SB_BAD_ARGUMENT); + ASSERT_EQ(CFE_SB_GetPipeOpts(SB_UT_ALTERNATE_INVALID_PIPEID, &Opts), CFE_SB_BAD_ARGUMENT); EVTSENT(CFE_SB_GETPIPEOPTS_ID_ERR_EID); @@ -2073,7 +2081,7 @@ void Test_GetPipeOpts_BadID(void) */ void Test_GetPipeOpts_BadPtr(void) { - CFE_SB_PipeId_t PipeID = 0; + CFE_SB_PipeId_t PipeID; SETUP(CFE_SB_CreatePipe(&PipeID, 4, "TestPipe1")); @@ -2090,7 +2098,7 @@ void Test_GetPipeOpts_BadPtr(void) */ void Test_GetPipeOpts(void) { - CFE_SB_PipeId_t PipeID = 0; + CFE_SB_PipeId_t PipeID; uint8 Opts = 0; SETUP(CFE_SB_CreatePipe(&PipeID, 4, "TestPipe1")); @@ -2137,7 +2145,7 @@ void Test_Subscribe_SubscribeEx(void) ASSERT(CFE_SB_SubscribeEx(MsgId, PipeId, Quality, MsgLim)); - EVTCNT(3); + EVTCNT(2); EVTSENT(CFE_SB_PIPE_ADDED_EID); EVTSENT(CFE_SB_SUBSCRIPTION_RCVD_EID); @@ -2151,7 +2159,7 @@ void Test_Subscribe_SubscribeEx(void) */ void Test_Subscribe_InvalidPipeId(void) { - CFE_SB_PipeId_t PipeId = 2; + CFE_SB_PipeId_t PipeId = SB_UT_PIPEID_2; CFE_SB_MsgId_t MsgId = SB_UT_ALTERNATE_INVALID_MID; ASSERT_EQ(CFE_SB_Subscribe(MsgId, PipeId), CFE_SB_BAD_ARGUMENT); @@ -2199,7 +2207,7 @@ void Test_Subscribe_MaxMsgLim(void) ASSERT(CFE_SB_SubscribeEx(MsgId, PipeId, Quality, MsgLim)); - EVTCNT(3); + EVTCNT(2); EVTSENT(CFE_SB_PIPE_ADDED_EID); @@ -2221,9 +2229,10 @@ void Test_Subscribe_DuplicateSubscription(void) ASSERT(CFE_SB_Subscribe(MsgId, PipeId)); ASSERT(CFE_SB_Subscribe(MsgId, PipeId)); - EVTCNT(5); + EVTCNT(4); EVTSENT(CFE_SB_PIPE_ADDED_EID); + EVTSENT(CFE_SB_DUP_SUBSCRIP_EID); TEARDOWN(CFE_SB_DeletePipe(PipeId)); @@ -2243,9 +2252,10 @@ void Test_Subscribe_LocalSubscription(void) ASSERT(CFE_SB_SubscribeLocal(MsgId, PipeId, MsgLim)); - EVTCNT(3); + EVTCNT(2); EVTSENT(CFE_SB_PIPE_ADDED_EID); + EVTSENT(CFE_SB_SUBSCRIPTION_RCVD_EID); TEARDOWN(CFE_SB_DeletePipe(PipeId)); @@ -2274,17 +2284,18 @@ void Test_Subscribe_MaxDestCount(void) { if (i < CFE_PLATFORM_SB_MAX_DEST_PER_PKT) { - SETUP(CFE_SB_Subscribe(MsgId, i)); + SETUP(CFE_SB_Subscribe(MsgId, PipeId[i])); } else { - ASSERT_EQ(CFE_SB_Subscribe(MsgId, i), CFE_SB_MAX_DESTS_MET); + ASSERT_EQ(CFE_SB_Subscribe(MsgId, PipeId[i]), CFE_SB_MAX_DESTS_MET); } } - EVTCNT(3 * (CFE_PLATFORM_SB_MAX_DEST_PER_PKT + 1)); + EVTCNT((2 * CFE_PLATFORM_SB_MAX_DEST_PER_PKT) + 3); EVTSENT(CFE_SB_PIPE_ADDED_EID); + EVTSENT(CFE_SB_MAX_DESTS_MET_EID); /* Delete pipes */ for (i = 0; i < CFE_PLATFORM_SB_MAX_DEST_PER_PKT + 1; i++) @@ -2368,7 +2379,7 @@ void Test_Subscribe_SendPrevSubs(void) ASSERT(CFE_SB_SendPrevSubsCmd(&SendPrevSubsMsg)); - EVTCNT(19); + EVTCNT(12); EVTSENT(CFE_SB_PART_SUB_PKT_EID); @@ -2384,7 +2395,7 @@ void Test_Subscribe_SendPrevSubs(void) void Test_Subscribe_PipeNonexistent(void) { CFE_SB_MsgId_t MsgId = SB_UT_CMD_MID; - CFE_SB_PipeId_t PipeId = 55; + CFE_SB_PipeId_t PipeId = SB_UT_ALTERNATE_INVALID_PIPEID; ASSERT_EQ(CFE_SB_Subscribe(MsgId, PipeId), CFE_SB_BAD_ARGUMENT); @@ -2413,7 +2424,7 @@ void Test_Subscribe_SubscriptionReporting(void) /* For internal TransmitMsg call that will report subscription */ MsgIdRpt = CFE_SB_ValueToMsgId(CFE_SB_ONESUB_TLM_MID); - Size = sizeof(CFE_SB.SubRprtMsg); + Size = sizeof(CFE_SB_SingleSubscriptionTlm_t); UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgIdRpt, sizeof(MsgIdRpt), false); UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); @@ -2426,7 +2437,7 @@ void Test_Subscribe_SubscriptionReporting(void) /* Subscribe to message: LOCAL */ ASSERT(CFE_SB_SubscribeFull(MsgId, PipeId, Quality, CFE_PLATFORM_SB_DEFAULT_MSG_LIMIT, CFE_SB_LOCAL)); - EVTCNT(8); + EVTCNT(6); EVTSENT(CFE_SB_SUBSCRIPTION_RPT_EID); @@ -2443,6 +2454,7 @@ void Test_Subscribe_SubscriptionReporting(void) void Test_Subscribe_InvalidPipeOwner(void) { CFE_SB_PipeId_t PipeId; + CFE_SB_PipeD_t *PipeDscPtr; CFE_SB_MsgId_t MsgId = SB_UT_TLM_MID; uint16 PipeDepth = 10; CFE_ES_ResourceID_t RealOwner; @@ -2450,10 +2462,11 @@ void Test_Subscribe_InvalidPipeOwner(void) SETUP(CFE_SB_CreatePipe(&PipeId, PipeDepth, "TestPipe")); /* Change owner of pipe through memory corruption */ - RealOwner = CFE_SB.PipeTbl[PipeId].AppId; + PipeDscPtr = CFE_SB_LocatePipeDescByID(PipeId); + RealOwner = PipeDscPtr->AppId; /* Choose a value that is sure not to be owner */ - CFE_SB.PipeTbl[PipeId].AppId = UT_SB_ResourceID_Modify(RealOwner, 1); + PipeDscPtr->AppId = UT_SB_ResourceID_Modify(RealOwner, 1); CFE_SB_Subscribe(MsgId, PipeId); EVTCNT(3); @@ -2461,7 +2474,7 @@ void Test_Subscribe_InvalidPipeOwner(void) EVTSENT(CFE_SB_SUB_INV_CALLER_EID); /* Restore owner id and delete pipe since test is complete */ - CFE_SB.PipeTbl[PipeId].AppId = RealOwner; + PipeDscPtr->AppId = RealOwner; TEARDOWN(CFE_SB_DeletePipe(PipeId)); } /* end Test_Subscribe_InvalidPipeOwner */ @@ -2496,7 +2509,7 @@ void Test_Unsubscribe_Basic(void) ASSERT(CFE_SB_Unsubscribe(MsgId, TestPipe)); - EVTCNT(4); + EVTCNT(3); EVTSENT(CFE_SB_SUBSCRIPTION_RCVD_EID); @@ -2524,7 +2537,7 @@ void Test_Unsubscribe_Local(void) ASSERT(CFE_SB_UnsubscribeLocal(SB_UT_LAST_VALID_MID, TestPipe)); - EVTCNT(5); + EVTCNT(4); EVTSENT(CFE_SB_SUBSCRIPTION_RCVD_EID); @@ -2539,6 +2552,7 @@ void Test_Unsubscribe_InvalParam(void) { CFE_SB_PipeId_t TestPipe; CFE_ES_ResourceID_t CallerId; + CFE_SB_PipeD_t *PipeDscPtr; uint16 PipeDepth = 50; CFE_SB_PipeId_t SavedPipeId; @@ -2558,17 +2572,18 @@ void Test_Unsubscribe_InvalParam(void) * bad pipe ID is caught by CFE_SB_GetPipeIdx() before it gets to * CFE_SB_ValidatePipeId() */ - SavedPipeId = CFE_SB.PipeTbl[0].PipeId; - CFE_SB.PipeTbl[0].PipeId = CFE_PLATFORM_SB_MAX_PIPES; - CFE_SB.PipeTbl[0].InUse = 1; - ASSERT_EQ(CFE_SB_Unsubscribe(SB_UT_FIRST_VALID_MID, CFE_PLATFORM_SB_MAX_PIPES), CFE_SB_BAD_ARGUMENT); + PipeDscPtr = CFE_SB_LocatePipeDescByID(TestPipe); + SavedPipeId = CFE_SB_PipeDescGetID(PipeDscPtr); + PipeDscPtr->PipeId = SB_UT_ALTERNATE_INVALID_PIPEID; + ASSERT_EQ(CFE_SB_Unsubscribe(SB_UT_FIRST_VALID_MID, TestPipe), CFE_SB_BAD_ARGUMENT); /* We must restore the old value so CFE_SB_DeletePipe() works */ - CFE_SB.PipeTbl[0].PipeId = SavedPipeId; + PipeDscPtr->PipeId = SavedPipeId; EVTCNT(4); EVTSENT(CFE_SB_UNSUB_ARG_ERR_EID); + EVTSENT(CFE_SB_UNSUB_INV_PIPE_EID); TEARDOWN(CFE_SB_DeletePipe(TestPipe)); @@ -2614,9 +2629,9 @@ void Test_Unsubscribe_InvalidPipe(void) SETUP(CFE_SB_CreatePipe(&TestPipe, PipeDepth, "TestPipe")); SETUP(CFE_SB_Subscribe(MsgId, TestPipe)); - ASSERT_EQ(CFE_SB_Unsubscribe(MsgId, TestPipe + 1), CFE_SB_BAD_ARGUMENT); + ASSERT_EQ(CFE_SB_Unsubscribe(MsgId, SB_UT_ALTERNATE_INVALID_PIPEID), CFE_SB_BAD_ARGUMENT); - EVTCNT(4); + EVTCNT(3); EVTSENT(CFE_SB_UNSUB_INV_PIPE_EID); @@ -2631,6 +2646,7 @@ void Test_Unsubscribe_InvalidPipeOwner(void) { CFE_SB_PipeId_t PipeId; CFE_SB_MsgId_t MsgId = SB_UT_TLM_MID; + CFE_SB_PipeD_t *PipeDscPtr; CFE_ES_ResourceID_t RealOwner; uint16 PipeDepth = 10; @@ -2639,17 +2655,18 @@ void Test_Unsubscribe_InvalidPipeOwner(void) SETUP(CFE_SB_Subscribe(MsgId, PipeId)); /* Change owner of pipe through memory corruption */ - RealOwner = CFE_SB.PipeTbl[PipeId].AppId; + PipeDscPtr = CFE_SB_LocatePipeDescByID(PipeId); + RealOwner = PipeDscPtr->AppId; /* Choose a value that is sure not be owner */ - CFE_SB.PipeTbl[PipeId].AppId = UT_SB_ResourceID_Modify(RealOwner, 1); + PipeDscPtr->AppId = UT_SB_ResourceID_Modify(RealOwner, 1); ASSERT_EQ(CFE_SB_Unsubscribe(MsgId, PipeId), CFE_SB_BAD_ARGUMENT); - EVTCNT(4); + EVTCNT(3); EVTSENT(CFE_SB_UNSUB_INV_CALLER_EID); - CFE_SB.PipeTbl[PipeId].AppId = RealOwner; + PipeDscPtr->AppId = RealOwner; TEARDOWN(CFE_SB_DeletePipe(PipeId)); @@ -2676,9 +2693,10 @@ void Test_Unsubscribe_FirstDestWithMany(void) ASSERT(CFE_SB_Unsubscribe(MsgId, TestPipe1)); - EVTCNT(10); + EVTCNT(7); EVTSENT(CFE_SB_SUBSCRIPTION_RCVD_EID); + EVTSENT(CFE_SB_SUBSCRIPTION_REMOVED_EID); TEARDOWN(CFE_SB_DeletePipe(TestPipe1)); TEARDOWN(CFE_SB_DeletePipe(TestPipe2)); @@ -2707,9 +2725,10 @@ void Test_Unsubscribe_MiddleDestWithMany(void) ASSERT(CFE_SB_Unsubscribe(MsgId, TestPipe2)); - EVTCNT(10); + EVTCNT(7); EVTSENT(CFE_SB_SUBSCRIPTION_RCVD_EID); + EVTSENT(CFE_SB_SUBSCRIPTION_REMOVED_EID); TEARDOWN(CFE_SB_DeletePipe(TestPipe1)); TEARDOWN(CFE_SB_DeletePipe(TestPipe2)); @@ -2739,9 +2758,10 @@ void Test_Unsubscribe_GetDestPtr(void) RouteId = CFE_SBR_GetRouteId(MsgId); ASSERT_TRUE(CFE_SB_GetDestPtr(RouteId, TestPipe2) == NULL); - EVTCNT(7); + EVTCNT(5); EVTSENT(CFE_SB_SUBSCRIPTION_RCVD_EID); + EVTSENT(CFE_SB_SUBSCRIPTION_REMOVED_EID); TEARDOWN(CFE_SB_DeletePipe(TestPipe1)); TEARDOWN(CFE_SB_DeletePipe(TestPipe2)); @@ -2846,7 +2866,7 @@ void Test_TransmitMsg_BasicSend(void) ASSERT(CFE_SB_TransmitMsg(&TlmPkt.Hdr.Msg, true)); - EVTCNT(3); + EVTCNT(2); TEARDOWN(CFE_SB_DeletePipe(PipeId)); @@ -2903,7 +2923,7 @@ void Test_TransmitMsg_SequenceCount(void) ASSERT_EQ(SeqCnt, 2); ASSERT_EQ(UT_GetStubCount(UT_KEY(CFE_MSG_SetSequenceCount)), 2); - EVTCNT(3); + EVTCNT(2); EVTSENT(CFE_SB_SUBSCRIPTION_RCVD_EID); SETUP(CFE_SB_Unsubscribe(MsgId, PipeId)); /* should have no subscribers now */ @@ -2948,7 +2968,7 @@ void Test_TransmitMsg_QueuePutError(void) ASSERT(CFE_SB_TransmitMsg(&TlmPkt.Hdr.Msg, true)); - EVTCNT(5); + EVTCNT(4); EVTSENT(CFE_SB_Q_WR_ERR_EID); @@ -2987,7 +3007,7 @@ void Test_TransmitMsg_PipeFull(void) /* Pipe overflow causes TransmitMsg to return CFE_SUCCESS */ ASSERT(CFE_SB_TransmitMsg(&TlmPkt.Hdr.Msg, true)); - EVTCNT(5); + EVTCNT(4); EVTSENT(CFE_SB_Q_FULL_ERR_EID); @@ -3028,7 +3048,7 @@ void Test_TransmitMsg_MsgLimitExceeded(void) */ ASSERT(CFE_SB_TransmitMsg(&TlmPkt.Hdr.Msg, true)); - EVTCNT(5); + EVTCNT(4); EVTSENT(CFE_SB_MSGID_LIM_ERR_EID); @@ -3059,7 +3079,7 @@ void Test_TransmitMsg_GetPoolBufErr(void) UT_SetDeferredRetcode(UT_KEY(CFE_ES_GetPoolBuf), 1, CFE_ES_ERR_MEM_BLOCK_SIZE); ASSERT_EQ(CFE_SB_TransmitMsg(&TlmPkt.Hdr.Msg, true), CFE_SB_BUF_ALOC_ERR); - EVTCNT(4); + EVTCNT(3); EVTSENT(CFE_SB_GET_BUF_ERR_EID); @@ -3164,7 +3184,7 @@ void Test_TransmitBuffer_IncrementSeqCnt(void) ASSERT_EQ(SeqCnt, 1); - EVTCNT(3); + EVTCNT(2); EVTSENT(CFE_SB_SUBSCRIPTION_RCVD_EID); @@ -3216,7 +3236,7 @@ void Test_TransmitBuffer_NoIncrement(void) ASSERT_TRUE(SendPtr == ReceivePtr); ASSERT_EQ(SeqCnt, 22); - EVTCNT(3); + EVTCNT(2); EVTSENT(CFE_SB_SUBSCRIPTION_RCVD_EID); @@ -3304,7 +3324,7 @@ void Test_TransmitMsg_DisabledDestination(void) ASSERT(CFE_SB_TransmitMsg(&TlmPkt.Hdr.Msg, true)); - EVTCNT(3); + EVTCNT(2); EVTSENT(CFE_SB_SUBSCRIPTION_RCVD_EID); @@ -3320,11 +3340,11 @@ void Test_TransmitBufferFull(void) CFE_SB_PipeId_t PipeId; CFE_SB_MsgId_t MsgId = SB_UT_TLM_MID; CFE_SB_BufferD_t SBBufD; - CFE_MSG_Message_t Msg; + CFE_SB_Buffer_t MsgBuf; int32 PipeDepth; CFE_SBR_RouteId_t RouteId; - SBBufD.Buffer = &Msg; + SBBufD.Buffer = &MsgBuf; PipeDepth = 2; SETUP(CFE_SB_CreatePipe(&PipeId, PipeDepth, "TestPipe")); SETUP(CFE_SB_Subscribe(MsgId, PipeId)); @@ -3333,7 +3353,7 @@ void Test_TransmitBufferFull(void) ASSERT(CFE_SB_TransmitBufferFull(&SBBufD, RouteId, MsgId)); - EVTCNT(3); + EVTCNT(2); TEARDOWN(CFE_SB_DeletePipe(PipeId)); @@ -3410,9 +3430,7 @@ void Test_ReceiveBuffer_API(void) void Test_ReceiveBuffer_InvalidPipeId(void) { CFE_SB_Buffer_t *SBBufPtr; - CFE_SB_PipeId_t InvalidPipeId = 20; - - CFE_SB.PipeTbl[InvalidPipeId].InUse = CFE_SB_NOT_IN_USE; + CFE_SB_PipeId_t InvalidPipeId = SB_UT_ALTERNATE_INVALID_PIPEID; ASSERT_EQ(CFE_SB_ReceiveBuffer(&SBBufPtr, InvalidPipeId, CFE_SB_POLL), CFE_SB_BAD_ARGUMENT); @@ -3502,7 +3520,7 @@ void Test_ReceiveBuffer_PipeReadError(void) UT_SetDeferredRetcode(UT_KEY(OS_QueueGet), 1, OS_ERROR); ASSERT_EQ(CFE_SB_ReceiveBuffer(&SBBufPtr, PipeId, CFE_SB_PEND_FOREVER), CFE_SB_PIPE_RD_ERR); - EVTCNT(3); + EVTCNT(2); EVTSENT(CFE_SB_Q_RD_ERR_EID); @@ -3519,7 +3537,6 @@ void Test_ReceiveBuffer_PendForever(void) CFE_SB_MsgId_t MsgId = SB_UT_TLM_MID; CFE_SB_PipeId_t PipeId; SB_UT_Test_Tlm_t TlmPkt; - CFE_SB_PipeD_t *PipeDscPtr; uint32 PipeDepth = 10; CFE_MSG_Type_t Type = CFE_MSG_Type_Tlm; CFE_MSG_Size_t Size = sizeof(TlmPkt); @@ -3535,14 +3552,10 @@ void Test_ReceiveBuffer_PendForever(void) ASSERT_TRUE(SBBufPtr != NULL); - EVTCNT(3); + EVTCNT(2); EVTSENT(CFE_SB_SUBSCRIPTION_RCVD_EID); - PipeDscPtr = CFE_SB_GetPipePtr(PipeId); - PipeDscPtr->ToTrashBuff = PipeDscPtr->CurrentBuff; - PipeDscPtr->CurrentBuff = NULL; - TEARDOWN(CFE_SB_DeletePipe(PipeId)); } /* end Test_ReceiveBuffer_PendForever */ @@ -3564,7 +3577,7 @@ void Test_CleanupApp_API(void) CFE_SB_ZeroCopyGetPtr(PipeDepth, &ZeroCpyBufHndl); /* Set second application ID to provide complete branch path coverage */ - CFE_SB.PipeTbl[1].InUse = CFE_SB_IN_USE; + CFE_SB.PipeTbl[1].PipeId = SB_UT_PIPEID_1; CFE_SB.PipeTbl[1].AppId = AppID; ASSERT_TRUE(CFE_SB.ZeroCopyTail != NULL); @@ -3579,7 +3592,7 @@ void Test_CleanupApp_API(void) ASSERT_TRUE(CFE_SB.ZeroCopyTail == NULL); - EVTCNT(3); + EVTCNT(2); EVTSENT(CFE_SB_PIPE_ADDED_EID); @@ -3724,7 +3737,6 @@ void Test_SB_SpecialCases(void) SB_UT_ADD_SUBTEST(Test_OS_MutSem_ErrLogic); SB_UT_ADD_SUBTEST(Test_ReqToSendEvent_ErrLogic); SB_UT_ADD_SUBTEST(Test_PutDestBlk_ErrLogic); - SB_UT_ADD_SUBTEST(Test_CFE_SB_GetPipeIdx); SB_UT_ADD_SUBTEST(Test_CFE_SB_Buffers); SB_UT_ADD_SUBTEST(Test_CFE_SB_BadPipeInfo); SB_UT_ADD_SUBTEST(Test_SB_TransmitMsgPaths_Nominal); @@ -3751,7 +3763,7 @@ void Test_OS_MutSem_ErrLogic(void) ASSERT(CFE_SB_Subscribe(MsgId, PipeId)); - EVTCNT(3); + EVTCNT(2); EVTSENT(CFE_SB_PIPE_ADDED_EID); EVTSENT(CFE_SB_SUBSCRIPTION_RCVD_EID); @@ -3796,19 +3808,6 @@ void Test_PutDestBlk_ErrLogic(void) } /* end Test_PutDestBlk_ErrLogic */ -/* -** Test internal function to get the pipe table index for the given pipe ID -*/ -void Test_CFE_SB_GetPipeIdx(void) -{ - CFE_SB.PipeTbl[0].PipeId = 0; - CFE_SB.PipeTbl[0].InUse = CFE_SB_NOT_IN_USE; - ASSERT_EQ(CFE_SB_GetPipeIdx(0), CFE_SB_INVALID_PIPE); - - EVTCNT(0); - -} /* end Test_CFE_SB_GetPipeIdx */ - /* ** Test functions that involve a buffer in the SB buffer pool */ @@ -3855,6 +3854,7 @@ void Test_CFE_SB_Buffers(void) void Test_CFE_SB_BadPipeInfo(void) { CFE_SB_PipeId_t PipeId; + CFE_SB_PipeD_t *PipeDscPtr; uint16 PipeDepth = 10; CFE_SB_Qos_t CFE_SB_Default_Qos; CFE_ES_ResourceID_t AppID; @@ -3862,17 +3862,17 @@ void Test_CFE_SB_BadPipeInfo(void) SETUP(CFE_SB_CreatePipe(&PipeId, PipeDepth, "TestPipe1")); /* Set the pipe ID to an erroneous value and attempt to delete the pipe */ - CFE_SB.PipeTbl[0].PipeId = 1; - CFE_SB.PipeTbl[0].InUse = 1; + PipeDscPtr = CFE_SB_LocatePipeDescByID(PipeId); + PipeDscPtr->PipeId = SB_UT_PIPEID_1; CFE_ES_GetAppID(&AppID); - ASSERT_EQ(CFE_SB_DeletePipeFull(0, AppID), CFE_SB_BAD_ARGUMENT); + ASSERT_EQ(CFE_SB_DeletePipeFull(SB_UT_PIPEID_0, AppID), CFE_SB_BAD_ARGUMENT); EVTCNT(2); /* Reset the pipe ID and delete the pipe */ - CFE_SB.PipeTbl[0].PipeId = 0; + PipeDscPtr->PipeId = PipeId; - ASSERT_EQ(CFE_SB_SubscribeFull(SB_UT_FIRST_VALID_MID ,0, CFE_SB_Default_Qos, + ASSERT_EQ(CFE_SB_SubscribeFull(SB_UT_FIRST_VALID_MID , PipeId, CFE_SB_Default_Qos, CFE_PLATFORM_SB_DEFAULT_MSG_LIMIT, 2), CFE_SB_BAD_ARGUMENT); EVTCNT(4); @@ -4034,7 +4034,7 @@ void Test_SB_TransmitMsgPaths_FullErr(void) ASSERT_TRUE(!UT_EventIsInHistory(CFE_SB_Q_FULL_ERR_EID_BIT)); - EVTCNT(3); + EVTCNT(2); TEARDOWN(CFE_SB_DeletePipe(PipeId)); } /* end Test_SB_TransmitMsgPaths */ @@ -4068,7 +4068,7 @@ void Test_SB_TransmitMsgPaths_WriteErr(void) ASSERT(CFE_SB_TransmitMsg(&TlmPkt.Hdr.Msg, true)); - EVTCNT(3); + EVTCNT(2); ASSERT_TRUE(!UT_EventIsInHistory(CFE_SB_Q_WR_ERR_EID)); @@ -4131,9 +4131,10 @@ void Test_ReceiveBuffer_UnsubResubPath(void) ASSERT_TRUE(SBBufPtr != NULL); - EVTCNT(6); + EVTCNT(4); EVTSENT(CFE_SB_SUBSCRIPTION_RCVD_EID); + EVTSENT(CFE_SB_SUBSCRIPTION_REMOVED_EID); TEARDOWN(CFE_SB_DeletePipe(PipeId)); diff --git a/fsw/cfe-core/unit-test/sb_UT.h b/fsw/cfe-core/unit-test/sb_UT.h index 1420e762a..d2acfb22b 100644 --- a/fsw/cfe-core/unit-test/sb_UT.h +++ b/fsw/cfe-core/unit-test/sb_UT.h @@ -2440,23 +2440,6 @@ void Test_ReqToSendEvent_ErrLogic(void); ******************************************************************************/ void Test_PutDestBlk_ErrLogic(void); -/*****************************************************************************/ -/** -** \brief Test internal function to get the pipe table index for the given pipe -** ID -** -** \par Description -** This function tests the internal function to get the pipe table index -** for the given pipe ID when the ID is not in use. -** -** \par Assumptions, External Events, and Notes: -** None -** -** \returns -** This function does not return a value. -******************************************************************************/ -void Test_CFE_SB_GetPipeIdx(void); - /*****************************************************************************/ /** ** \brief Test functions that involve a buffer in the SB buffer pool diff --git a/fsw/cfe-core/ut-stubs/ut_sb_stubs.c b/fsw/cfe-core/ut-stubs/ut_sb_stubs.c index f34d7be20..a6bf2162d 100644 --- a/fsw/cfe-core/ut-stubs/ut_sb_stubs.c +++ b/fsw/cfe-core/ut-stubs/ut_sb_stubs.c @@ -289,7 +289,7 @@ int32 CFE_SB_GetPipeIdByName(CFE_SB_PipeId_t *PipeIdPtr, const char *PipeName) else { status = CFE_SB_BAD_ARGUMENT; - *PipeIdPtr = 0; + *PipeIdPtr = CFE_SB_INVALID_PIPE; } }