From 4dd5bdaad9a984f3de3537271ece0563022a46ee Mon Sep 17 00:00:00 2001 From: Guillaume Lethuillier Date: Fri, 24 Apr 2020 19:52:50 +0200 Subject: [PATCH 01/21] Fix #637, Remove old CFE_ARINC653-related tests --- fsw/cfe-core/unit-test/es_UT.c | 173 --------------------------------- fsw/cfe-core/unit-test/es_UT.h | 25 ----- 2 files changed, 198 deletions(-) diff --git a/fsw/cfe-core/unit-test/es_UT.c b/fsw/cfe-core/unit-test/es_UT.c index 065f3a061..6bbfe43e6 100644 --- a/fsw/cfe-core/unit-test/es_UT.c +++ b/fsw/cfe-core/unit-test/es_UT.c @@ -46,10 +46,6 @@ extern CFE_ES_CDSBlockDesc_t CFE_ES_CDSBlockDesc; extern CFE_ES_TaskData_t CFE_ES_TaskData; extern CFE_ES_CDSPool_t CFE_ES_CDSMemPool; -#ifdef CFE_ARINC653 -extern CFE_ES_StaticStartupTable_t CFE_ES_StaticStartupTable[]; -#endif - extern int32 dummy_function(void); /* @@ -294,10 +290,6 @@ void UtTest_Setup(void) UT_ADD_TEST(TestESMempool); UT_ADD_TEST(TestSysLog); UT_ADD_TEST(TestBackground); - -#ifdef CFE_ARINC653 - UT_ADD_TEST(TestStaticApp); -#endif } /* @@ -7006,168 +6998,3 @@ void TestBackground(void) "CFE_ES_BackgroundTask - Nominal, CFE_ES_Global.BackgroundTask.NumJobsRunning (%u) == 1", (unsigned int)CFE_ES_Global.BackgroundTask.NumJobsRunning); } - - - -#ifdef CFE_ARINC653 -void TestStaticApp(void) -{ - int j; - uint32 Id; - uint32 LibraryIdPtr; - CFE_ES_AppMainFuncPtr_t MainFunc = 0; - - /* Test successful static app creation */ - ES_ResetUnitTest(); - CFE_ES_Global.AppTable[0].AppState = CFE_ES_AppState_RUNNING; - CFE_ES_Global.AppTable[1].AppState = CFE_ES_AppState_UNDEFINED; - CFE_ES_Global.TaskTable[1].RecordUsed = false; - UT_Report(__FILE__, __LINE__, - CFE_ES_StaticAppCreate(&Id, - MainFunc, - "AppName", - 170, - 4096, - 1) == CFE_SUCCESS && - CFE_ES_Global.TaskTable[1].RecordUsed == true, - "CFE_ES_StaticAppCreate", - "Create static application; successful"); - - /* Test static app creation with a task create failure */ - ES_ResetUnitTest(); - UT_SetForceFail(UT_KEY(OS_TaskCreate), OS_ERROR); - UT_Report(__FILE__, __LINE__, - CFE_ES_StaticAppCreate(&Id, - MainFunc, - "AppName", - 170, - 4096, - 1) == CFE_ES_ERR_APP_CREATE, - "CFE_ES_StaticAppCreate", - "Task create error"); - - /* Test static app creation specifying a slot already in use */ - ES_ResetUnitTest(); - CFE_ES_Global.TaskTable[0].RecordUsed = true; - UT_Report(__FILE__, __LINE__, - CFE_ES_StaticAppCreate(&Id, - MainFunc, - "AppName", - 170, - 4096, - 1) == CFE_SUCCESS, - "CFE_ES_StaticAppCreate", - "Task slot in use"); - - /* Test static app creation with no free slots available */ - ES_ResetUnitTest(); - - for (j = 0; j < CFE_PLATFORM_ES_MAX_APPLICATIONS; j++) - { - CFE_ES_Global.AppTable[j].AppState = CFE_ES_AppState_RUNNING; - } - - UT_Report(__FILE__, __LINE__, - CFE_ES_StaticAppCreate(&Id, - MainFunc, - "AppName", - 170, - 4096, - 1) == CFE_ES_ERR_APP_CREATE, - "CFE_ES_StaticAppCreate", - "No free application slots available"); - - /* Test successful static shared library initialization */ - ES_ResetUnitTest(); - UT_SetLibInitRtn(CFE_SUCCESS); - LibraryIdPtr = 1; - CFE_ES_Global.LibTable[0].RecordUsed = false; - UT_Report(__FILE__, __LINE__, - CFE_ES_InitStaticLibrary(&LibraryIdPtr, - (CFE_ES_LibInitFuncPtr_t) UT_LibInit, - "LibName") == CFE_SUCCESS && - LibraryIdPtr == 0, - "CFE_ES_InitStaticLibrary", - "Static library initialization; successful"); - - /* Test static shared library initialization with a library load failure */ - ES_ResetUnitTest(); - UT_SetLibInitRtn(CFE_ES_ERR_LOAD_LIB); - CFE_ES_Global.LibTable[0].RecordUsed = false; - UT_Report(__FILE__, __LINE__, - CFE_ES_InitStaticLibrary(&LibraryIdPtr, - (CFE_ES_LibInitFuncPtr_t) UT_LibInit, - "LibName") == CFE_ES_ERR_LOAD_LIB, - "CFE_ES_InitStaticLibrary", - "Shared library initialization failure"); - - /* Test static shared library initialization with no free - * slots available - */ - ES_ResetUnitTest(); - - for (j = 0; j < CFE_PLATFORM_ES_MAX_LIBRARIES; j++) - { - CFE_ES_Global.LibTable[j].RecordUsed = true; - } - - UT_Report(__FILE__, __LINE__, - CFE_ES_InitStaticLibrary(&LibraryIdPtr, - (CFE_ES_LibInitFuncPtr_t) UT_LibInit, - "LibName") == CFE_ES_ERR_LOAD_LIB, - "CFE_ES_InitStaticLibrary", - "No free library slots available"); - - /* Test successful static application initialization */ - ES_ResetUnitTest(); - - for (j = 0; j < CFE_PLATFORM_ES_MAX_LIBRARIES; j++) - { - CFE_ES_Global.LibTable[j].RecordUsed = false; - } - - strncpy(CFE_ES_StaticStartupTable[0].Name, - "StaticAppName", OS_MAX_API_NAME); - CFE_ES_StaticStartupTable[0].Name[OS_MAX_API_NAME - 1] = '\0'; - CFE_ES_StaticStartupTable[0].ObjectType = CFE_ES_STATIC_APP; - CFE_ES_StaticStartupTable[0].ExceptionAction = - CFE_ES_ExceptionAction_RESTART_APP + 1; - CFE_ES_StartStaticApplications(CFE_PSP_RST_TYPE_PROCESSOR); - UT_Report(__FILE__, __LINE__, - CFE_ES_StaticStartupTable[0].ExceptionAction == - CFE_ES_ExceptionAction_PROC_RESTART && - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_NO_MESSAGE]), - "CFE_ES_StartStaticApplications", - "*Not implemented* Initialize static application; successful"); - - /* Test successful static library initialization */ - ES_ResetUnitTest(); - CFE_ES_StaticStartupTable[0].ObjectType = CFE_ES_STATIC_LIB; - CFE_ES_StartStaticApplications(CFE_PSP_RST_TYPE_PROCESSOR); - UT_Report(__FILE__, __LINE__, - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_NO_MESSAGE]), - "CFE_ES_StartStaticApplications", - "*Not implemented* Initialize static shared library; successful"); - - /* Test successful static application initialization null action */ - ES_ResetUnitTest(); - CFE_ES_StaticStartupTable[0].ObjectType = CFE_ES_STATIC_NULL; - CFE_ES_StartStaticApplications(CFE_PSP_RST_TYPE_PROCESSOR); - UT_Report(__FILE__, __LINE__, - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_NO_MESSAGE]), - "CFE_ES_StartStaticApplications", - "*Not implemented* No action"); - - /* Test successful static library initialization with an invalid - * entry type - */ - ES_ResetUnitTest(); - CFE_ES_StaticStartupTable[0].ObjectType = 0xff; - CFE_ES_StartStaticApplications(CFE_PSP_RST_TYPE_PROCESSOR); - UT_Report(__FILE__, __LINE__, - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_NO_MESSAGE]), - "CFE_ES_StartStaticApplications", - "*Not implemented* Unexpected entry type"); -} -#endif - diff --git a/fsw/cfe-core/unit-test/es_UT.h b/fsw/cfe-core/unit-test/es_UT.h index b597c7a1d..6c35bb802 100644 --- a/fsw/cfe-core/unit-test/es_UT.h +++ b/fsw/cfe-core/unit-test/es_UT.h @@ -355,29 +355,4 @@ void TestESMempool(void); void TestSysLog(void); -#ifdef CFE_ARINC653 -/*****************************************************************************/ -/** -** \brief Perform tests on the cFE applications from statically linked code -** -** \par Description -** This function tests the code for creating and loading cFE -** applications from statically linked code, and for initializing -** static libraries. -** -** \par Assumptions, External Events, and Notes: -** None -** -** \returns -** This function does not return a value. -** -** \sa #UT_InitData, #UT_Report, CFE_ES_StaticAppCreate, #UT_SetOSFail -** \sa #UT_SetLibInitRtn, #CFE_ES_InitStaticLibrary -** \sa #CFE_ES_StartStaticApplications -** -******************************************************************************/ -void TestStaticApp(void); -#endif - - #endif /* _es_ut_h_ */ From cff18abec37ba52be6592d2453772287d4393648 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Mon, 27 Apr 2020 08:48:51 -0400 Subject: [PATCH 02/21] Fix #641, string operations on GCC9 Ensure clean build, no warnings on string operations using GCC 9.3.0. Some string ops were genuinely incorrect (particularly in UT) but some were perfectly OK and handled correctly per the C spec. In particular the new "rules" that GCC9 warns about make the strncat library function (and some others) somewhat off-limits even if used correctly. --- fsw/cfe-core/src/es/cfe_es_api.c | 2 +- fsw/cfe-core/src/es/cfe_es_cds.c | 3 ++- fsw/cfe-core/src/es/cfe_es_task.c | 16 +++++++++++----- fsw/cfe-core/src/tbl/cfe_tbl_internal.c | 6 ++++-- fsw/cfe-core/src/tbl/cfe_tbl_task_cmds.c | 14 ++++++++------ fsw/cfe-core/unit-test/es_UT.c | 2 +- fsw/cfe-core/unit-test/tbl_UT.c | 11 +++++++---- fsw/cfe-core/unit-test/time_UT.c | 16 +++++++--------- fsw/cfe-core/unit-test/ut_support.c | 3 ++- 9 files changed, 43 insertions(+), 30 deletions(-) diff --git a/fsw/cfe-core/src/es/cfe_es_api.c b/fsw/cfe-core/src/es/cfe_es_api.c index 44e528037..985ad9b9d 100644 --- a/fsw/cfe-core/src/es/cfe_es_api.c +++ b/fsw/cfe-core/src/es/cfe_es_api.c @@ -775,7 +775,7 @@ int32 CFE_ES_GetAppName(char *AppName, uint32 AppId, uint32 BufferLength) { if ( CFE_ES_Global.AppTable[AppId].AppState != CFE_ES_AppState_UNDEFINED ) { - strncpy(AppName, (char *)CFE_ES_Global.AppTable[AppId].StartParams.Name, BufferLength); + strncpy(AppName, (char *)CFE_ES_Global.AppTable[AppId].StartParams.Name, BufferLength - 1); AppName[BufferLength - 1] = '\0'; Result = CFE_SUCCESS; } diff --git a/fsw/cfe-core/src/es/cfe_es_cds.c b/fsw/cfe-core/src/es/cfe_es_cds.c index ff8cf85ff..4cd699447 100644 --- a/fsw/cfe-core/src/es/cfe_es_cds.c +++ b/fsw/cfe-core/src/es/cfe_es_cds.c @@ -296,7 +296,8 @@ int32 CFE_ES_RegisterCDSEx(CFE_ES_CDSHandle_t *HandlePtr, int32 BlockSize, const RegRecPtr->Table = CriticalTbl; /* Save CDS Name in Registry */ - strncpy(RegRecPtr->Name, Name, CFE_ES_CDS_MAX_FULL_NAME_LEN); + strncpy(RegRecPtr->Name, Name, sizeof(RegRecPtr->Name)-1); + RegRecPtr->Name[sizeof(RegRecPtr->Name)-1] = 0; /* Return the index into the registry as the handle to the CDS */ *HandlePtr = RegIndx; diff --git a/fsw/cfe-core/src/es/cfe_es_task.c b/fsw/cfe-core/src/es/cfe_es_task.c index bb5dc5fdf..115dbcfbb 100644 --- a/fsw/cfe-core/src/es/cfe_es_task.c +++ b/fsw/cfe-core/src/es/cfe_es_task.c @@ -207,6 +207,7 @@ int32 CFE_ES_TaskInit(void) cpuaddr CfeSegmentAddr; char EventBuffer[CFE_MISSION_EVS_MAX_MESSAGE_LENGTH]; char VersionBuffer[CFE_MISSION_EVS_MAX_MESSAGE_LENGTH]; + uint32 Remaining; /* ** Register the Application @@ -367,17 +368,21 @@ int32 CFE_ES_TaskInit(void) snprintf(EventBuffer, sizeof(EventBuffer), "Mission %s.%s", GLOBAL_CONFIGDATA.MissionVersion, GLOBAL_CONFIGDATA.Config); } - if(strcmp(GLOBAL_CONFIGDATA.MissionVersion, GLOBAL_CONFIGDATA.CfeVersion)) + Remaining = sizeof(EventBuffer)-strlen(EventBuffer)-1; + if(Remaining > 0 && strcmp(GLOBAL_CONFIGDATA.MissionVersion, GLOBAL_CONFIGDATA.CfeVersion)) { snprintf(VersionBuffer, sizeof(VersionBuffer), ", CFE: %s", GLOBAL_CONFIGDATA.CfeVersion); - strncat(EventBuffer, VersionBuffer, sizeof(EventBuffer)-strlen(EventBuffer)-1); + VersionBuffer[Remaining] = 0; + strcat(EventBuffer, VersionBuffer); + Remaining = sizeof(EventBuffer)-strlen(EventBuffer)-1; } - if(strcmp(GLOBAL_CONFIGDATA.MissionVersion, GLOBAL_CONFIGDATA.OsalVersion)) + if(Remaining > 0 && strcmp(GLOBAL_CONFIGDATA.MissionVersion, GLOBAL_CONFIGDATA.OsalVersion)) { snprintf(VersionBuffer, sizeof(VersionBuffer), ", OSAL: %s", GLOBAL_CONFIGDATA.OsalVersion); - strncat(EventBuffer, VersionBuffer, sizeof(EventBuffer)-strlen(EventBuffer)-1); + VersionBuffer[Remaining] = 0; + strcat(EventBuffer, VersionBuffer); } Status = CFE_EVS_SendEvent(CFE_ES_VERSION_INF_EID, @@ -1916,7 +1921,8 @@ int32 CFE_ES_DumpCDSRegistryCmd(const CFE_ES_DumpCDSRegistry_t *data) DumpRecord.ByteAlignSpare1 = 0; /* strncpy will zero out any unused buffer - memset not necessary */ - strncpy(DumpRecord.Name, RegRecPtr->Name, sizeof(DumpRecord.Name)); + strncpy(DumpRecord.Name, RegRecPtr->Name, sizeof(DumpRecord.Name)-1); + DumpRecord.Name[sizeof(DumpRecord.Name)-1] = 0; /* Output Registry Dump Record to Registry Dump File */ Status = OS_write(FileDescriptor, diff --git a/fsw/cfe-core/src/tbl/cfe_tbl_internal.c b/fsw/cfe-core/src/tbl/cfe_tbl_internal.c index 68e563c4d..109b2b612 100644 --- a/fsw/cfe-core/src/tbl/cfe_tbl_internal.c +++ b/fsw/cfe-core/src/tbl/cfe_tbl_internal.c @@ -1110,10 +1110,12 @@ int32 CFE_TBL_UpdateInternal( CFE_TBL_Handle_t TblHandle, /* Save source description with active buffer */ strncpy(RegRecPtr->Buffers[0].DataSource, CFE_TBL_TaskData.LoadBuffs[RegRecPtr->LoadInProgress].DataSource, - OS_MAX_PATH_LEN); + sizeof(RegRecPtr->Buffers[0].DataSource)-1); + RegRecPtr->Buffers[0].DataSource[sizeof(RegRecPtr->Buffers[0].DataSource)-1] = 0; strncpy(RegRecPtr->LastFileLoaded, CFE_TBL_TaskData.LoadBuffs[RegRecPtr->LoadInProgress].DataSource, - OS_MAX_PATH_LEN); + sizeof(RegRecPtr->LastFileLoaded)-1); + RegRecPtr->LastFileLoaded[sizeof(RegRecPtr->LastFileLoaded)-1] = 0; /* Save the file creation time from the loaded file into the Table Registry */ RegRecPtr->Buffers[0].FileCreateTimeSecs = diff --git a/fsw/cfe-core/src/tbl/cfe_tbl_task_cmds.c b/fsw/cfe-core/src/tbl/cfe_tbl_task_cmds.c index e697ce72d..6c83341c7 100644 --- a/fsw/cfe-core/src/tbl/cfe_tbl_task_cmds.c +++ b/fsw/cfe-core/src/tbl/cfe_tbl_task_cmds.c @@ -768,7 +768,8 @@ CFE_TBL_CmdProcRet_t CFE_TBL_DumpToFile( const char *DumpFilename, const char *T if (Status == sizeof(CFE_FS_Header_t)) { /* Initialize the Table Image Header for the Dump File */ - strncpy(TblFileHeader.TableName, TableName, sizeof(TblFileHeader.TableName)); + strncpy(TblFileHeader.TableName, TableName, sizeof(TblFileHeader.TableName)-1); + TblFileHeader.TableName[sizeof(TblFileHeader.TableName)-1] = 0; TblFileHeader.Offset = 0; TblFileHeader.NumBytes = TblSizeInBytes; TblFileHeader.Reserved = 0; @@ -814,7 +815,8 @@ CFE_TBL_CmdProcRet_t CFE_TBL_DumpToFile( const char *DumpFilename, const char *T /* Save file information statistics for housekeeping telemetry */ strncpy(CFE_TBL_TaskData.HkPacket.Payload.LastFileDumped, DumpFilename, - sizeof(CFE_TBL_TaskData.HkPacket.Payload.LastFileDumped)); + sizeof(CFE_TBL_TaskData.HkPacket.Payload.LastFileDumped)-1); + CFE_TBL_TaskData.HkPacket.Payload.LastFileDumped[sizeof(CFE_TBL_TaskData.HkPacket.Payload.LastFileDumped)-1] = 0; /* Increment Successful Command Counter */ ReturnCode = CFE_TBL_INC_CMD_CTR; @@ -1206,8 +1208,8 @@ int32 CFE_TBL_DumpRegistryCmd(const CFE_TBL_DumpRegistry_t *data) memset(DumpRecord.LastFileLoaded, 0, OS_MAX_PATH_LEN); memset(DumpRecord.OwnerAppName, 0, OS_MAX_API_NAME); - strncpy(DumpRecord.Name, RegRecPtr->Name, CFE_TBL_MAX_FULL_NAME_LEN); - strncpy(DumpRecord.LastFileLoaded, RegRecPtr->LastFileLoaded, OS_MAX_PATH_LEN); + strncpy(DumpRecord.Name, RegRecPtr->Name, sizeof(DumpRecord.Name)-1); + strncpy(DumpRecord.LastFileLoaded, RegRecPtr->LastFileLoaded, sizeof(DumpRecord.LastFileLoaded)-1); /* Walk the access descriptor list to determine the number of users */ DumpRecord.NumUsers = 0; @@ -1221,11 +1223,11 @@ int32 CFE_TBL_DumpRegistryCmd(const CFE_TBL_DumpRegistry_t *data) /* Determine the name of the owning application */ if (RegRecPtr->OwnerAppId != CFE_TBL_NOT_OWNED) { - CFE_ES_GetAppName(DumpRecord.OwnerAppName, RegRecPtr->OwnerAppId, OS_MAX_API_NAME); + CFE_ES_GetAppName(DumpRecord.OwnerAppName, RegRecPtr->OwnerAppId, sizeof(DumpRecord.OwnerAppName)); } else { - strncpy(DumpRecord.OwnerAppName, "--UNOWNED--", OS_MAX_API_NAME); + strncpy(DumpRecord.OwnerAppName, "--UNOWNED--", sizeof(DumpRecord.OwnerAppName)-1); } /* Output Registry Dump Record to Registry Dump File */ diff --git a/fsw/cfe-core/unit-test/es_UT.c b/fsw/cfe-core/unit-test/es_UT.c index 065f3a061..534bf4f4b 100644 --- a/fsw/cfe-core/unit-test/es_UT.c +++ b/fsw/cfe-core/unit-test/es_UT.c @@ -2696,7 +2696,7 @@ void TestTask(void) sizeof(CmdBuf.StartAppCmd.Payload.AppFileName)); strncpy((char *) CmdBuf.StartAppCmd.Payload.AppEntryPoint, "entrypoint", sizeof(CmdBuf.StartAppCmd.Payload.AppEntryPoint)); - strncpy((char *) CmdBuf.StartAppCmd.Payload.Application, "appNameIntentionallyTooLongToFitIntoDestinationBuffer", + memset(CmdBuf.StartAppCmd.Payload.Application, 'x', sizeof(CmdBuf.StartAppCmd.Payload.Application)); CmdBuf.StartAppCmd.Payload.Priority = 160; CmdBuf.StartAppCmd.Payload.StackSize = 8192; diff --git a/fsw/cfe-core/unit-test/tbl_UT.c b/fsw/cfe-core/unit-test/tbl_UT.c index d878ccb2c..da8baf873 100644 --- a/fsw/cfe-core/unit-test/tbl_UT.c +++ b/fsw/cfe-core/unit-test/tbl_UT.c @@ -3725,11 +3725,14 @@ void Test_CFE_TBL_Manage(void) * later */ CFE_TBL_TaskData.DumpControlBlocks[0].DumpBufferPtr = WorkingBufferPtr; - memcpy(CFE_TBL_TaskData.DumpControlBlocks[0]. + strncpy(CFE_TBL_TaskData.DumpControlBlocks[0]. DumpBufferPtr->DataSource, - "MyDumpFilename", OS_MAX_PATH_LEN); - memcpy(CFE_TBL_TaskData.DumpControlBlocks[0].TableName, - "ut_cfe_tbl.UT_Table2", CFE_TBL_MAX_FULL_NAME_LEN); + "MyDumpFilename", OS_MAX_PATH_LEN-1); + CFE_TBL_TaskData.DumpControlBlocks[0]. + DumpBufferPtr->DataSource[OS_MAX_PATH_LEN-1] = 0; + strncpy(CFE_TBL_TaskData.DumpControlBlocks[0].TableName, + "ut_cfe_tbl.UT_Table2", CFE_TBL_MAX_FULL_NAME_LEN-1); + CFE_TBL_TaskData.DumpControlBlocks[0].TableName[CFE_TBL_MAX_FULL_NAME_LEN-1] = 0; CFE_TBL_TaskData.DumpControlBlocks[0].Size = RegRecPtr->Size; RegRecPtr->DumpControlIndex = 0; RtnCode = CFE_TBL_Manage(App1TblHandle2); diff --git a/fsw/cfe-core/unit-test/time_UT.c b/fsw/cfe-core/unit-test/time_UT.c index 7e1d9e94d..a43d426e9 100644 --- a/fsw/cfe-core/unit-test/time_UT.c +++ b/fsw/cfe-core/unit-test/time_UT.c @@ -1266,7 +1266,7 @@ void Test_ConvertCFEFS(void) void Test_Print(void) { int result; - char testDesc[UT_MAX_MESSAGE_LENGTH]; + char testDesc[1+UT_MAX_MESSAGE_LENGTH]; CFE_TIME_SysTime_t time; #ifdef UT_VERBOSE @@ -1279,8 +1279,8 @@ void Test_Print(void) time.Seconds = 0; CFE_TIME_Print(testDesc, time); result = !strcmp(testDesc, "1980-001-00:00:00.00000"); - strncat(testDesc," Zero time value", UT_MAX_MESSAGE_LENGTH); - testDesc[UT_MAX_MESSAGE_LENGTH - 1] = '\0'; + strncat(testDesc," Zero time value", + UT_MAX_MESSAGE_LENGTH - strlen(testDesc)); UT_Report(__FILE__, __LINE__, result, "CFE_TIME_Print", @@ -1296,8 +1296,7 @@ void Test_Print(void) result = !strcmp(testDesc, "1980-001-00:00:59.00000"); strncat(testDesc, " Seconds overflow if CFE_MISSION_TIME_EPOCH_SECOND > 0", - UT_MAX_MESSAGE_LENGTH); - testDesc[UT_MAX_MESSAGE_LENGTH - 1] = '\0'; + UT_MAX_MESSAGE_LENGTH - strlen(testDesc)); UT_Report(__FILE__, __LINE__, result, "CFE_TIME_Print", @@ -1309,8 +1308,8 @@ void Test_Print(void) time.Seconds = 1041472984; CFE_TIME_Print(testDesc, time); result = !strcmp(testDesc, "2013-001-02:03:04.00005"); - strncat(testDesc," Mission representative time", UT_MAX_MESSAGE_LENGTH); - testDesc[UT_MAX_MESSAGE_LENGTH - 1] = '\0'; + strncat(testDesc," Mission representative time", + UT_MAX_MESSAGE_LENGTH - strlen(testDesc)); UT_Report(__FILE__, __LINE__, result, "CFE_TIME_Print", @@ -1323,8 +1322,7 @@ void Test_Print(void) CFE_TIME_Print(testDesc, time); result = !strcmp(testDesc, "2116-038-06:28:15.99999"); strncat(testDesc," Maximum seconds/subseconds values", - UT_MAX_MESSAGE_LENGTH); - testDesc[UT_MAX_MESSAGE_LENGTH - 1] = '\0'; + UT_MAX_MESSAGE_LENGTH - strlen(testDesc)); UT_Report(__FILE__, __LINE__, result, "CFE_TIME_Print", diff --git a/fsw/cfe-core/unit-test/ut_support.c b/fsw/cfe-core/unit-test/ut_support.c index f1a363716..7c9281e8b 100644 --- a/fsw/cfe-core/unit-test/ut_support.c +++ b/fsw/cfe-core/unit-test/ut_support.c @@ -82,7 +82,8 @@ void UT_Init(const char *subsys) int8 i; /* Copy the application name for later use */ - strncpy(UT_subsys, subsys, 5); + strncpy(UT_subsys, subsys, sizeof(UT_subsys)-1); + UT_subsys[sizeof(UT_subsys)-1] = 0; snprintf(UT_appname, 80, "ut_cfe_%s", subsys); /* Convert to upper case */ From a3230cb755a157aab08cb90057dff48ba54191fa Mon Sep 17 00:00:00 2001 From: Jacob Hageman Date: Mon, 27 Apr 2020 11:38:28 -0400 Subject: [PATCH 03/21] Fix #484, Deprecate output to shell command --- cmake/sample_defs/cpu1_msgids.h | 6 +- fsw/cfe-core/src/es/cfe_es_shell.c | 6 + fsw/cfe-core/src/es/cfe_es_task.c | 8 +- fsw/cfe-core/src/es/cfe_es_task.h | 5 +- fsw/cfe-core/src/inc/cfe_es_msg.h | 22 ++- fsw/cfe-core/unit-test/es_UT.c | 274 ----------------------------- fsw/cfe-core/unit-test/es_UT.h | 23 +-- 7 files changed, 41 insertions(+), 303 deletions(-) diff --git a/cmake/sample_defs/cpu1_msgids.h b/cmake/sample_defs/cpu1_msgids.h index 9a2c6c4fe..3e7ebc0bf 100644 --- a/cmake/sample_defs/cpu1_msgids.h +++ b/cmake/sample_defs/cpu1_msgids.h @@ -86,7 +86,11 @@ #define CFE_TBL_REG_TLM_MID CFE_MISSION_TLM_MID_BASE1 + CFE_MISSION_TBL_REG_TLM_MSG /* 0x080C */ #define CFE_SB_ALLSUBS_TLM_MID CFE_MISSION_TLM_MID_BASE1 + CFE_MISSION_SB_ALLSUBS_TLM_MSG /* 0x080D */ #define CFE_SB_ONESUB_TLM_MID CFE_MISSION_TLM_MID_BASE1 + CFE_MISSION_SB_ONESUB_TLM_MSG /* 0x080E */ -#define CFE_ES_SHELL_TLM_MID CFE_MISSION_TLM_MID_BASE1 + CFE_MISSION_ES_SHELL_TLM_MSG /* 0x080F */ + +#ifndef CFE_OMIT_DEPRECATED_6_7 + #define CFE_ES_SHELL_TLM_MID CFE_MISSION_TLM_MID_BASE1 + CFE_MISSION_ES_SHELL_TLM_MSG /* 0x080F */ +#endif + #define CFE_ES_MEMSTATS_TLM_MID CFE_MISSION_TLM_MID_BASE1 + CFE_MISSION_ES_MEMSTATS_TLM_MSG /* 0x0810 */ /* diff --git a/fsw/cfe-core/src/es/cfe_es_shell.c b/fsw/cfe-core/src/es/cfe_es_shell.c index 72a0ea1bc..5f2b343bb 100644 --- a/fsw/cfe-core/src/es/cfe_es_shell.c +++ b/fsw/cfe-core/src/es/cfe_es_shell.c @@ -44,6 +44,11 @@ #include +#ifndef CFE_OMIT_DEPRECATED_6_7 /* Remove entire file eventually */ +/* Note - Plan to implement the list functions as real commands, + * shell output no longer part of cFS Framework, recommend implementation in an app if needed + */ + #define CFE_ES_CHECKSIZE 3 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* CFE_ES_ShellOutputCommand() -- Pass thru string to O/S shell or to ES */ @@ -424,3 +429,4 @@ int32 CFE_ES_ListResources(int32 fd) */ return Result; } +#endif /* CFE_OMIT_DEPRECATED_6_7 */ diff --git a/fsw/cfe-core/src/es/cfe_es_task.c b/fsw/cfe-core/src/es/cfe_es_task.c index 215aa52a7..478bb0c11 100644 --- a/fsw/cfe-core/src/es/cfe_es_task.c +++ b/fsw/cfe-core/src/es/cfe_es_task.c @@ -248,12 +248,14 @@ int32 CFE_ES_TaskInit(void) CFE_SB_ValueToMsgId(CFE_ES_HK_TLM_MID), sizeof(CFE_ES_TaskData.HkPacket), true); +#ifndef CFE_OMIT_DEPRECATED_6_7 /* ** Initialize shell output packet (clear user data area) */ CFE_SB_InitMsg(&CFE_ES_TaskData.ShellPacket, CFE_SB_ValueToMsgId(CFE_ES_SHELL_TLM_MID), sizeof(CFE_ES_TaskData.ShellPacket), true); +#endif /* ** Initialize single application telemetry packet @@ -465,12 +467,14 @@ void CFE_ES_TaskPipe(CFE_SB_MsgPtr_t Msg) } break; +#ifndef CFE_OMIT_DEPRECATED_6_7 case CFE_ES_SHELL_CC: if (CFE_ES_VerifyCmdLength(Msg, sizeof(CFE_ES_Shell_t))) { CFE_ES_ShellCmd((CFE_ES_Shell_t*)Msg); } break; +#endif case CFE_ES_START_APP_CC: if (CFE_ES_VerifyCmdLength(Msg, sizeof(CFE_ES_StartApp_t))) @@ -832,7 +836,7 @@ int32 CFE_ES_RestartCmd(const CFE_ES_Restart_t *data) return CFE_SUCCESS; } /* End of CFE_ES_RestartCmd() */ - +#ifndef CFE_OMIT_DEPRECATED_6_7 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* */ /* CFE_ES_ShellCmd() -- Pass thru string to O/S shell */ @@ -877,7 +881,7 @@ int32 CFE_ES_ShellCmd(const CFE_ES_Shell_t *data) return CFE_SUCCESS; } /* End of CFE_ES_ShellCmd() */ - +#endif /* CFE_OMIT_DEPRECATED_6_7 */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* */ diff --git a/fsw/cfe-core/src/es/cfe_es_task.h b/fsw/cfe-core/src/es/cfe_es_task.h index d90a11a42..30e64f4c4 100644 --- a/fsw/cfe-core/src/es/cfe_es_task.h +++ b/fsw/cfe-core/src/es/cfe_es_task.h @@ -77,11 +77,12 @@ typedef struct */ CFE_ES_HousekeepingTlm_t HkPacket; - +#ifndef CFE_OMIT_DEPRECATED_6_7 /* ** ES Shell output telemetry packet */ CFE_ES_ShellTlm_t ShellPacket; +#endif /* ** Single application telemetry packet @@ -152,7 +153,9 @@ int32 CFE_ES_HousekeepingCmd(const CCSDS_CommandPacket_t *data); int32 CFE_ES_NoopCmd(const CFE_ES_Noop_t *Cmd); int32 CFE_ES_ResetCountersCmd(const CFE_ES_ResetCounters_t *data); int32 CFE_ES_RestartCmd(const CFE_ES_Restart_t *data); +#ifndef CFE_OMIT_DEPRECATED_6_7 int32 CFE_ES_ShellCmd(const CFE_ES_Shell_t *data); +#endif int32 CFE_ES_StartAppCmd(const CFE_ES_StartApp_t *data); int32 CFE_ES_StopAppCmd(const CFE_ES_StopApp_t *data); int32 CFE_ES_RestartAppCmd(const CFE_ES_RestartApp_t *data); diff --git a/fsw/cfe-core/src/inc/cfe_es_msg.h b/fsw/cfe-core/src/inc/cfe_es_msg.h index bbd67a208..fe82d51b4 100644 --- a/fsw/cfe-core/src/inc/cfe_es_msg.h +++ b/fsw/cfe-core/src/inc/cfe_es_msg.h @@ -170,7 +170,9 @@ */ #define CFE_ES_RESTART_CC 2 -/** \cfeescmd Executive Services O/S Shell Command +#ifndef CFE_OMIT_DEPRECATED_6_7 +/** \cfeescmd DEPRECATED: Executive Services O/S Shell Command +** \deprecated ** ** \par Description ** This command passes an ASCII string as a command line to the @@ -217,6 +219,7 @@ ** \sa */ #define CFE_ES_SHELL_CC 3 +#endif /* CFE_OMIT_DEPRECATED_6_7 */ /** \cfeescmd Load and Start an Application ** @@ -1152,8 +1155,10 @@ typedef struct CFE_ES_RestartCmd_Payload_t Payload; } CFE_ES_Restart_t; +#ifndef CFE_OMIT_DEPRECATED_6_7 /** -** \brief Shell Command +** \brief DEPRECATED: Shell Command +** \deprecated ** ** For command details, see #CFE_ES_SHELL_CC ** @@ -1166,11 +1171,16 @@ typedef struct be written */ } CFE_ES_ShellCmd_Payload_t; +/** + * \deprecated + */ typedef struct { uint8 CmdHeader[CFE_SB_CMD_HDR_SIZE]; /**< \brief cFE Software Bus Command Message Header */ CFE_ES_ShellCmd_Payload_t Payload; } CFE_ES_Shell_t; +#endif /* CFE_OMIT_DEPRECATED_6_7 */ + /** ** \brief Payload format for commands which accept a single file name @@ -1575,8 +1585,10 @@ typedef struct } CFE_ES_HousekeepingTlm_t; +#ifndef CFE_OMIT_DEPRECATED_6_7 /** -** \cfeestlm OS Shell Output Packet +** \cfeestlm DEPRECATED: OS Shell Output Packet +** \deprecated **/ typedef struct { @@ -1584,11 +1596,15 @@ typedef struct that was received in response to an OS Shell Command */ } CFE_ES_ShellPacket_Payload_t; +/** + * \deprecated + */ typedef struct { uint8 TlmHeader[CFE_SB_TLM_HDR_SIZE]; /**< \brief cFE Software Bus Telemetry Message Header */ CFE_ES_ShellPacket_Payload_t Payload; }CFE_ES_ShellTlm_t; +#endif /* CFE_OMIT_DEPRECATED_6_7 */ /*************************************************************************/ diff --git a/fsw/cfe-core/unit-test/es_UT.c b/fsw/cfe-core/unit-test/es_UT.c index 1963ded0d..b1ab5f08f 100644 --- a/fsw/cfe-core/unit-test/es_UT.c +++ b/fsw/cfe-core/unit-test/es_UT.c @@ -84,11 +84,6 @@ static const UT_TaskPipeDispatchId_t UT_TPID_CFE_ES_CMD_RESTART_CC = .CommandCode = CFE_ES_RESTART_CC }; -static const UT_TaskPipeDispatchId_t UT_TPID_CFE_ES_CMD_SHELL_CC = -{ - .MsgId = CFE_SB_MSGID_WRAP_VALUE(CFE_ES_CMD_MID), - .CommandCode = CFE_ES_SHELL_CC -}; static const UT_TaskPipeDispatchId_t UT_TPID_CFE_ES_CMD_START_APP_CC = { .MsgId = CFE_SB_MSGID_WRAP_VALUE(CFE_ES_CMD_MID), @@ -286,7 +281,6 @@ void UtTest_Setup(void) UT_ADD_TEST(TestStartupErrorPaths); UT_ADD_TEST(TestApps); UT_ADD_TEST(TestERLog); - UT_ADD_TEST(TestShell); UT_ADD_TEST(TestTask); UT_ADD_TEST(TestPerf); UT_ADD_TEST(TestAPI); @@ -2121,66 +2115,6 @@ void TestApps(void) CFE_ES_ListResourcesDebug() == CFE_SUCCESS, "CFE_ES_ListResourcesDebug", "Get OS information failures"); - - /* Fail the first time, then succeed on the second in order to test - * both paths - */ - UT_SetDeferredRetcode(UT_KEY(OS_MutSemGetInfo), 1, OS_ERROR); - UT_SetDeferredRetcode(UT_KEY(OS_BinSemGetInfo), 1, OS_ERROR); - UT_SetDeferredRetcode(UT_KEY(OS_CountSemGetInfo), 1, OS_ERROR); - UT_SetDeferredRetcode(UT_KEY(OS_TaskGetInfo), 1, OS_ERROR); - UT_SetDeferredRetcode(UT_KEY(OS_QueueGetInfo), 1, OS_ERROR); - UT_SetDeferredRetcode(UT_KEY(OS_TimerGetInfo), 1, OS_ERROR); - UT_SetDeferredRetcode(UT_KEY(OS_FDGetInfo), 1, OS_ERROR); - UT_SetDeferredRetcode(UT_KEY(OS_write), 1, OS_ERROR); - UT_Report(__FILE__, __LINE__, - CFE_ES_ListResources(0) == OS_ERROR, - "CFE_ES_ListResources", - "Get task info failed"); - - /* Fail the file write the second time in order to test the second path */ - UT_SetDeferredRetcode(UT_KEY(OS_write), 2, OS_ERROR); - UT_Report(__FILE__, __LINE__, - CFE_ES_ListResources(0) == OS_ERROR, - "CFE_ES_ListResources", - "File write failed (second path)"); - - /* Fail the file write the third time in order to test the third path */ - UT_SetDeferredRetcode(UT_KEY(OS_write), 3, OS_ERROR); - UT_Report(__FILE__, __LINE__, - CFE_ES_ListResources(0) == OS_ERROR, - "CFE_ES_ListResources", - "File write failed (third path)"); - - /* Fail the file write the fourth time in order to test the fourth path */ - UT_SetDeferredRetcode(UT_KEY(OS_write), 4, OS_ERROR); - UT_Report(__FILE__, __LINE__, - CFE_ES_ListResources(0) == OS_ERROR, - "CFE_ES_ListResources", - "File write failed (fourth path)"); - - /* Fail the file write the fifth time in order to test the fifth path */ - UT_SetDeferredRetcode(UT_KEY(OS_write), 5, OS_ERROR); - UT_Report(__FILE__, __LINE__, - CFE_ES_ListResources(0) == OS_ERROR, - "CFE_ES_ListResources", - "File write failed (fifth path)"); - - /* Fail the file write the sixth time in order to test the sixth path */ - UT_SetDeferredRetcode(UT_KEY(OS_write), 6, OS_ERROR); - UT_Report(__FILE__, __LINE__, - CFE_ES_ListResources(0) == OS_ERROR, - "CFE_ES_ListResources", - "File write failed (sixth path)"); - - /* Fail the file write the seventh time in order to test the seventh - * path - */ - UT_SetDeferredRetcode(UT_KEY(OS_write), 7, OS_ERROR); - UT_Report(__FILE__, __LINE__, - CFE_ES_ListResources(0) == OS_ERROR, - "CFE_ES_ListResources", - "File write failed (seventh path)"); } void TestERLog(void) @@ -2280,181 +2214,6 @@ void TestERLog(void) "No log entry rollover; no description; no context"); } -void TestShell(void) -{ - uint32 Id, Id2; - uint32 TestObjId, TestObjId2; - -#ifdef UT_VERBOSE - UT_Text("Begin Test Shell Command\n"); -#endif - - /* Test shell output command using a non-existent ES command */ - ES_ResetUnitTest(); - UT_Report(__FILE__, __LINE__, - CFE_ES_ShellOutputCommand("ES_NoSuchThing", - "./FS_Test_File_Name") == - CFE_ES_ERR_SHELL_CMD, - "CFE_ES_ShellOutputCommand", - "Invalid ES command"); - - /* Test shell output command using a valid OS command */ - ES_ResetUnitTest(); - UT_Report(__FILE__, __LINE__, - CFE_ES_ShellOutputCommand("ls", "") == CFE_SUCCESS, - "CFE_ES_ShellOutputCommand", - "Send OS command"); - - /* Test shell output command using an ES list applications command */ - ES_ResetUnitTest(); - OS_TaskCreate(&TestObjId, "UT", NULL, NULL, 0, 0, 0); - Id = ES_UT_OSALID_TO_ARRAYIDX(TestObjId); - CFE_ES_Global.TaskTable[Id].TaskId = TestObjId; - CFE_ES_Global.TaskTable[Id].RecordUsed = true; - CFE_ES_Global.TaskTable[Id].AppId = Id; - CFE_ES_Global.AppTable[Id].AppState = CFE_ES_AppState_RUNNING; - UT_Report(__FILE__, __LINE__, - CFE_ES_ShellOutputCommand("ES_ListApps", "") == CFE_SUCCESS, - "CFE_ES_ShellOutputCommand", - "Send ES list applications command"); - CFE_ES_Global.TaskTable[Id].RecordUsed = false; - - /* Test shell output command using an ES list tasks command */ - ES_ResetUnitTest(); - OS_TaskCreate(&TestObjId, "UT", NULL, NULL, 0, 0, 0); - Id = ES_UT_OSALID_TO_ARRAYIDX(TestObjId); - CFE_ES_Global.TaskTable[Id].TaskId = TestObjId; - CFE_ES_Global.TaskTable[Id].RecordUsed = true; - CFE_ES_Global.TaskTable[Id].AppId = Id; - CFE_ES_Global.AppTable[Id].AppState = CFE_ES_AppState_RUNNING; - UT_Report(__FILE__, __LINE__, - CFE_ES_ShellOutputCommand("ES_ListTasks", "") == CFE_SUCCESS, - "CFE_ES_ShellOutputCommand", - "Send ES list tasks command"); - CFE_ES_Global.TaskTable[Id].RecordUsed = false; - - /* Test shell output command using an ES list resources command. Alter - * the OS_lseek() response to increase branch path coverage - */ - ES_ResetUnitTest(); - UT_SetDeferredRetcode(UT_KEY(OS_lseek), 1, CFE_PLATFORM_ES_MAX_SHELL_PKT + 1); - UT_Report(__FILE__, __LINE__, - CFE_ES_ShellOutputCommand("ES_ListResources", "") == CFE_SUCCESS, - "CFE_ES_ShellOutputCommand", - "Send ES list resources command"); - - /* Test shell output command using a valid OS command but with a failed - * OS lseek - */ - ES_ResetUnitTest(); - UT_SetDeferredRetcode(UT_KEY(OS_lseek), 1, CFE_PLATFORM_ES_MAX_SHELL_PKT - 2); - UT_SetForceFail(UT_KEY(OS_lseek), OS_ERROR); - UT_Report(__FILE__, __LINE__, - CFE_ES_ShellOutputCommand("ls", "") == CFE_ES_ERR_SHELL_CMD, - "CFE_ES_ShellOutputCommand", - "OS command; OS lseek failure"); - - /* Test shell output command using a valid OS command to start sending - * packets down - */ - ES_ResetUnitTest(); - UT_SetDeferredRetcode(UT_KEY(OS_lseek), 2, CFE_PLATFORM_ES_MAX_SHELL_PKT * 2 + 1); - UT_Report(__FILE__, __LINE__, - CFE_ES_ShellOutputCommand("ls", "") == CFE_SUCCESS, - "CFE_ES_ShellOutputCommand", - "Multiple packets to send down"); - - /* Test shell output command using a valid ES command but with a failed - * OS create - */ - ES_ResetUnitTest(); - UT_SetForceFail(UT_KEY(OS_creat), OS_ERROR); - UT_Report(__FILE__, __LINE__, - CFE_ES_ShellOutputCommand("ES_ListApps", - "") == CFE_ES_ERR_SHELL_CMD, - "CFE_ES_ShellOutputCommand", - "ES command; OS create failure"); - - /* Test shell output command using a valid ES command but with a failed - * OS lseek - */ - ES_ResetUnitTest(); - UT_SetForceFail(UT_KEY(OS_lseek), OS_ERROR); - UT_Report(__FILE__, __LINE__, - CFE_ES_ShellOutputCommand("ES_ListApps", - "") == CFE_ES_ERR_SHELL_CMD, - "CFE_ES_ShellOutputCommand", - "ES command; OS lseek failed"); - - /* Test list application function with a failed OS write */ - ES_ResetUnitTest(); - UT_SetDeferredRetcode(UT_KEY(OS_write), 1, OS_ERROR); - OS_TaskCreate(&TestObjId, "UT", NULL, NULL, 0, 0, 0); - Id = ES_UT_OSALID_TO_ARRAYIDX(TestObjId); - OS_TaskCreate(&TestObjId2, "UT", NULL, NULL, 0, 0, 0); - Id2 = ES_UT_OSALID_TO_ARRAYIDX(TestObjId2); - CFE_ES_Global.AppTable[Id].AppState = CFE_ES_AppState_RUNNING; - CFE_ES_Global.AppTable[Id2].AppState = CFE_ES_AppState_RUNNING; - UT_Report(__FILE__, __LINE__, - CFE_ES_ListApplications(Id) == OS_ERROR, - "CFE_ES_ListApplications", - "File write error"); - CFE_ES_Global.AppTable[Id].AppState = CFE_ES_AppState_UNDEFINED; - CFE_ES_Global.AppTable[Id2].AppState = CFE_ES_AppState_UNDEFINED; - - /* Test list application function with a failed OS seek */ - ES_ResetUnitTest(); - UT_SetDeferredRetcode(UT_KEY(OS_lseek), 1, OS_ERROR); - UT_Report(__FILE__, __LINE__, - CFE_ES_ListTasks(0) == OS_ERROR, - "CFE_ES_ListTasks", - "File seek error"); - - /* Test list application function with a failed OS write */ - ES_ResetUnitTest(); - UT_SetDeferredRetcode(UT_KEY(OS_write), 1, OS_ERROR); - UT_Report(__FILE__, __LINE__, - CFE_ES_ListTasks(0) == OS_ERROR, - "CFE_ES_ListTasks", - "File write error"); - - /* Test list application function with a failed OS write on a - * subsequent pass - */ - ES_ResetUnitTest(); - OS_TaskCreate(&TestObjId, "UT", NULL, NULL, 0, 0, 0); - Id = ES_UT_OSALID_TO_ARRAYIDX(TestObjId); - OS_TaskCreate(&TestObjId2, "UT", NULL, NULL, 0, 0, 0); - Id2 = ES_UT_OSALID_TO_ARRAYIDX(TestObjId2); - CFE_ES_Global.TaskTable[Id].RecordUsed = true; - CFE_ES_Global.AppTable[Id].AppState = CFE_ES_AppState_RUNNING; - CFE_ES_Global.TaskTable[Id].AppId = Id2; - CFE_ES_Global.TaskTable[Id2].RecordUsed = true; - CFE_ES_Global.AppTable[Id2].AppState = CFE_ES_AppState_RUNNING; - CFE_ES_Global.TaskTable[Id2].AppId = Id2; - UT_SetDeferredRetcode(UT_KEY(OS_write), 2, OS_ERROR); - UT_Report(__FILE__, __LINE__, - CFE_ES_ListTasks(0) == OS_ERROR, - "CFE_ES_ListTasks", - "File write error (second pass)"); - - /* Test list application function with a failure to get the task - * information - */ - ES_ResetUnitTest(); - UT_SetDeferredRetcode(UT_KEY(OS_write), 3, OS_ERROR); - OS_TaskCreate(&TestObjId, "UT", NULL, NULL, 0, 0, 0); - Id = ES_UT_OSALID_TO_ARRAYIDX(TestObjId); - OS_TaskCreate(&TestObjId2, "UT", NULL, NULL, 0, 0, 0); - Id2 = ES_UT_OSALID_TO_ARRAYIDX(TestObjId2); - CFE_ES_Global.TaskTable[Id2].RecordUsed = true; - CFE_ES_Global.TaskTable[Id2].AppId = Id; - UT_Report(__FILE__, __LINE__, - CFE_ES_ListTasks(0) == CFE_ES_ERR_TASKID, - "CFE_ES_ListTasks", - "Get task info error"); -} - void TestTask(void) { uint32 Id; @@ -2465,7 +2224,6 @@ void TestTask(void) CFE_SB_Msg_t Msg; CFE_ES_NoArgsCmd_t NoArgsCmd; CFE_ES_Restart_t RestartCmd; - CFE_ES_Shell_t ShellCmd; CFE_ES_StartApp_t StartAppCmd; CFE_ES_StopApp_t StopAppCmd; CFE_ES_RestartApp_t RestartAppCmd; @@ -2668,29 +2426,6 @@ void TestTask(void) "CFE_ES_RestartCmd", "Invalid restart type"); - /* Test shell command failure */ - ES_ResetUnitTest(); - memset(&CmdBuf, 0, sizeof(CmdBuf)); - strncpy((char *) CmdBuf.ShellCmd.Payload.CmdString, "ES_NOAPP", - sizeof(CmdBuf.ShellCmd.Payload.CmdString)); - UT_CallTaskPipe(CFE_ES_TaskPipe, &CmdBuf.Msg, sizeof(CFE_ES_Shell_t), - UT_TPID_CFE_ES_CMD_SHELL_CC); - UT_Report(__FILE__, __LINE__, - UT_EventIsInHistory(CFE_ES_SHELL_ERR_EID), - "CFE_ES_ShellCmd", - "Shell command fail"); - - /* Test successful shell command */ - ES_ResetUnitTest(); - strncpy((char *) CmdBuf.ShellCmd.Payload.CmdString, "ls", - sizeof(CmdBuf.ShellCmd.Payload.CmdString)); - UT_CallTaskPipe(CFE_ES_TaskPipe, &CmdBuf.Msg, sizeof(CFE_ES_Shell_t), - UT_TPID_CFE_ES_CMD_SHELL_CC); - UT_Report(__FILE__, __LINE__, - UT_EventIsInHistory(CFE_ES_SHELL_INF_EID), - "CFE_ES_ShellCmd", - "Shell command success"); - /* Test successful app create */ ES_ResetUnitTest(); memset(&CmdBuf, 0, sizeof(CmdBuf)); @@ -3567,15 +3302,6 @@ void TestTask(void) "CFE_ES_RestartCmd", "Power on reset restart type"); - /* Test sending a shell command with an invalid command length */ - ES_ResetUnitTest(); - UT_CallTaskPipe(CFE_ES_TaskPipe, &CmdBuf.Msg, 0, - UT_TPID_CFE_ES_CMD_SHELL_CC); - UT_Report(__FILE__, __LINE__, - UT_EventIsInHistory(CFE_ES_LEN_ERR_EID), - "CFE_ES_ShellCmd", - "Shell command; invalid command length"); - /* Test sending a start application command with an invalid command * length */ diff --git a/fsw/cfe-core/unit-test/es_UT.h b/fsw/cfe-core/unit-test/es_UT.h index b597c7a1d..16a248490 100644 --- a/fsw/cfe-core/unit-test/es_UT.h +++ b/fsw/cfe-core/unit-test/es_UT.h @@ -164,27 +164,6 @@ void TestApps(void); ******************************************************************************/ void TestERLog(void); -/*****************************************************************************/ -/** -** \brief Performs tests on the ES shell commanding system contained in -** cfe_es_shell.c -** -** \par Description -** This function tests the shell output command paths in the function -** CFE_ES_ShellOutputCommand. -** -** \par Assumptions, External Events, and Notes: -** None -** -** \returns -** This function does not return a value. -** -** \sa #UT_Text, #UT_SetOSFail, #UT_Report, #CFE_ES_ShellOutputCommand -** \sa #UT_SetRtnCode -** -******************************************************************************/ -void TestShell(void); - /*****************************************************************************/ /** ** \brief Performs tests of the ground command functions contained in @@ -204,7 +183,7 @@ void TestShell(void); ** \sa #CFE_ES_TaskInit, #UT_SetSBTotalMsgLen, #UT_SendMsg ** \sa #UT_SetBSPloadAppFileResult, #UT_SetStatusBSPResetArea ** \sa #CFE_ES_HousekeepingCmd, #CFE_ES_NoopCmd, #CFE_ES_ResetCountersCmd -** \sa #CFE_ES_RestartCmd, #CFE_ES_ShellCmd, #CFE_ES_StartAppCmd +** \sa #CFE_ES_RestartCmd, #CFE_ES_StartAppCmd ** \sa #CFE_ES_StopAppCmd, #CFE_ES_RestartAppCmd, #CFE_ES_ReloadAppCmd ** \sa #CFE_ES_QueryOneCmd, #CFE_ES_QueryAllCmd, #CFE_ES_QueryAllTasksCmd ** \sa #CFE_ES_ClearSyslogCmd, #CFE_ES_OverWriteSyslogCmd From f211a064bf24839f45e0ef25f1f4b8cae16c3bf6 Mon Sep 17 00:00:00 2001 From: Jacob Hageman Date: Tue, 28 Apr 2020 10:38:43 -0400 Subject: [PATCH 04/21] Fix #523, SB Subscription report control on separate MID --- cmake/sample_defs/cpu1_msgids.h | 2 + cmake/sample_defs/sample_mission_cfg.h | 2 + fsw/cfe-core/src/sb/cfe_sb_task.c | 61 +++++++++++++++++--------- fsw/cfe-core/unit-test/sb_UT.c | 48 +++++++++++++++----- 4 files changed, 81 insertions(+), 32 deletions(-) diff --git a/cmake/sample_defs/cpu1_msgids.h b/cmake/sample_defs/cpu1_msgids.h index 9a2c6c4fe..eddd60824 100644 --- a/cmake/sample_defs/cpu1_msgids.h +++ b/cmake/sample_defs/cpu1_msgids.h @@ -58,6 +58,8 @@ #define CFE_TBL_SEND_HK_MID CFE_MISSION_CMD_MID_BASE1 + CFE_MISSION_TBL_SEND_HK_MSG /* 0x180C */ #define CFE_TIME_SEND_HK_MID CFE_MISSION_CMD_MID_BASE1 + CFE_MISSION_TIME_SEND_HK_MSG /* 0x180D */ +#define CFE_SB_SUB_RPT_CTRL_MID CFE_MISSION_CMD_MID_BASE1 + CFE_MISSION_SB_SUB_RPT_CTRL_MSG /* 0x180E */ + #define CFE_TIME_TONE_CMD_MID CFE_MISSION_CMD_MID_BASE1 + CFE_MISSION_TIME_TONE_CMD_MSG /* 0x1810 */ #define CFE_TIME_1HZ_CMD_MID CFE_MISSION_CMD_MID_BASE1 + CFE_MISSION_TIME_1HZ_CMD_MSG /* 0x1811 */ diff --git a/cmake/sample_defs/sample_mission_cfg.h b/cmake/sample_defs/sample_mission_cfg.h index 979da27a7..6043ecb32 100644 --- a/cmake/sample_defs/sample_mission_cfg.h +++ b/cmake/sample_defs/sample_mission_cfg.h @@ -422,6 +422,8 @@ #define CFE_MISSION_TBL_SEND_HK_MSG 12 #define CFE_MISSION_TIME_SEND_HK_MSG 13 +#define CFE_MISSION_SB_SUB_RPT_CTRL_MSG 14 + #define CFE_MISSION_TIME_TONE_CMD_MSG 16 #define CFE_MISSION_TIME_1HZ_CMD_MSG 17 diff --git a/fsw/cfe-core/src/sb/cfe_sb_task.c b/fsw/cfe-core/src/sb/cfe_sb_task.c index 88e4cece2..b368c3c88 100644 --- a/fsw/cfe-core/src/sb/cfe_sb_task.c +++ b/fsw/cfe-core/src/sb/cfe_sb_task.c @@ -263,6 +263,13 @@ int32 CFE_SB_AppInit(void){ CFE_ES_WriteToSysLog("SB:Subscribe to HK Request Failed:RC=0x%08X\n",(unsigned int)Status); return Status; }/* end if */ + + Status = CFE_SB_Subscribe(CFE_SB_ValueToMsgId(CFE_SB_SUB_RPT_CTRL_MID),CFE_SB.CmdPipe); + + if(Status != CFE_SUCCESS){ + CFE_ES_WriteToSysLog("SB:Subscribe to Subscription Report Request Failed:RC=0x%08X\n",(unsigned int)Status); + return Status; + }/* end if */ /* Ensure a ground commanded reset does not get blocked if SB mem pool */ /* becomes fully configured (DCR6772) */ @@ -359,6 +366,39 @@ void CFE_SB_ProcessCmdPipePkt(void) { CFE_SB_SendHKTlmCmd((CCSDS_CommandPacket_t *)CFE_SB.CmdPipePktPtr); break; + case CFE_SB_SUB_RPT_CTRL_MID: + /* Note: Command counter not incremented for this command */ + switch (CFE_SB_GetCmdCode(CFE_SB.CmdPipePktPtr)) { + case CFE_SB_SEND_PREV_SUBS_CC: + if (CFE_SB_VerifyCmdLength(CFE_SB.CmdPipePktPtr, sizeof(CFE_SB_SendPrevSubs_t))) + { + CFE_SB_SendPrevSubsCmd((CFE_SB_SendPrevSubs_t *)CFE_SB.CmdPipePktPtr); + } + break; + + case CFE_SB_ENABLE_SUB_REPORTING_CC: + if (CFE_SB_VerifyCmdLength(CFE_SB.CmdPipePktPtr, sizeof(CFE_SB_EnableSubReporting_t))) + { + CFE_SB_EnableSubReportingCmd((CFE_SB_EnableSubReporting_t *)CFE_SB.CmdPipePktPtr); + } + break; + + case CFE_SB_DISABLE_SUB_REPORTING_CC: + if (CFE_SB_VerifyCmdLength(CFE_SB.CmdPipePktPtr, sizeof(CFE_SB_DisableSubReporting_t))) + { + CFE_SB_DisableSubReportingCmd((CFE_SB_DisableSubReporting_t *)CFE_SB.CmdPipePktPtr); + } + break; + + default: + CFE_EVS_SendEvent(CFE_SB_BAD_CMD_CODE_EID,CFE_EVS_EventType_ERROR, + "Invalid Cmd, Unexpected Command Code %d", + (int)CFE_SB_GetCmdCode(CFE_SB.CmdPipePktPtr)); + CFE_SB.HKTlmMsg.Payload.CommandErrorCounter++; + break; + } /* end switch on cmd code */ + break; + case CFE_SB_CMD_MID: switch (CFE_SB_GetCmdCode(CFE_SB.CmdPipePktPtr)) { case CFE_SB_NOOP_CC: @@ -418,27 +458,6 @@ void CFE_SB_ProcessCmdPipePkt(void) { } break; - case CFE_SB_SEND_PREV_SUBS_CC: - if (CFE_SB_VerifyCmdLength(CFE_SB.CmdPipePktPtr, sizeof(CFE_SB_SendPrevSubs_t))) - { - CFE_SB_SendPrevSubsCmd((CFE_SB_SendPrevSubs_t *)CFE_SB.CmdPipePktPtr); - } - break; - - case CFE_SB_ENABLE_SUB_REPORTING_CC: - if (CFE_SB_VerifyCmdLength(CFE_SB.CmdPipePktPtr, sizeof(CFE_SB_EnableSubReporting_t))) - { - CFE_SB_EnableSubReportingCmd((CFE_SB_EnableSubReporting_t *)CFE_SB.CmdPipePktPtr); - } - break; - - case CFE_SB_DISABLE_SUB_REPORTING_CC: - if (CFE_SB_VerifyCmdLength(CFE_SB.CmdPipePktPtr, sizeof(CFE_SB_DisableSubReporting_t))) - { - CFE_SB_DisableSubReportingCmd((CFE_SB_DisableSubReporting_t *)CFE_SB.CmdPipePktPtr); - } - break; - default: CFE_EVS_SendEvent(CFE_SB_BAD_CMD_CODE_EID,CFE_EVS_EventType_ERROR, "Invalid Cmd, Unexpected Command Code %d", diff --git a/fsw/cfe-core/unit-test/sb_UT.c b/fsw/cfe-core/unit-test/sb_UT.c index b6d4a3917..20f7e1645 100644 --- a/fsw/cfe-core/unit-test/sb_UT.c +++ b/fsw/cfe-core/unit-test/sb_UT.c @@ -657,7 +657,7 @@ void Test_SB_AppInit_EVSSendEvtFail(void) TestStat = CFE_FAIL; } - ExpRtn = 5; + ExpRtn = 7; ActRtn = UT_GetNumEventsSent(); if (ActRtn != ExpRtn) @@ -849,7 +849,7 @@ void Test_SB_AppInit_GetPoolFail(void) #endif SB_ResetUnitTest(); - UT_SetDeferredRetcode(UT_KEY(CFE_ES_GetPoolBuf), 3, ForcedRtnVal); + UT_SetDeferredRetcode(UT_KEY(CFE_ES_GetPoolBuf), 4, ForcedRtnVal); ExpRtn = ForcedRtnVal; ActRtn = CFE_SB_AppInit(); @@ -863,7 +863,7 @@ void Test_SB_AppInit_GetPoolFail(void) TestStat = CFE_FAIL; } - ExpRtn = 5; + ExpRtn = 7; ActRtn = UT_GetNumEventsSent(); if (ActRtn != ExpRtn) @@ -910,7 +910,7 @@ void Test_SB_AppInit_PutPoolFail(void) TestStat = CFE_FAIL; } - ExpRtn = 5; + ExpRtn = 7; ActRtn = UT_GetNumEventsSent(); if (ActRtn != ExpRtn) @@ -961,7 +961,7 @@ void Test_SB_Main_RcvErr(void) SB_ResetUnitTest(); UT_SetDeferredRetcode(UT_KEY(OS_QueueGet), 1, -1); CFE_SB_TaskMain(); - ExpRtn = 8; + ExpRtn = 10; ActRtn = UT_GetNumEventsSent(); if (ActRtn != ExpRtn) @@ -1007,7 +1007,7 @@ void Test_SB_Main_InitErr(void) SB_ResetUnitTest(); UT_SetDeferredRetcode(UT_KEY(CFE_ES_PutPoolBuf), 1, -1); CFE_SB_TaskMain(); - ExpRtn = 5; + ExpRtn = 7; ActRtn = UT_GetNumEventsSent(); if (ActRtn != ExpRtn) @@ -1244,7 +1244,7 @@ void Test_SB_Cmds_RoutingInfoDef(void) CFE_SB.CmdPipePktPtr = (CFE_SB_MsgPtr_t) &WriteFileCmd; CFE_SB_ProcessCmdPipePkt(); - ExpRtn = 9; + ExpRtn = 12; ActRtn = UT_GetNumEventsSent(); if (ActRtn != ExpRtn) @@ -1475,7 +1475,7 @@ void Test_SB_Cmds_RoutingInfoWriteFail(void) TestStat = CFE_FAIL; } - ExpRtn = 9; + ExpRtn = 11; ActRtn = UT_GetNumEventsSent(); if (ActRtn != ExpRtn) @@ -2718,7 +2718,7 @@ void Test_SB_Cmds_SendPrevSubs(void) #endif SB_ResetUnitTest(); - CFE_SB_InitMsg(&NoParamCmd, CFE_SB_ValueToMsgId(CFE_SB_CMD_MID), sizeof(CFE_SB_SendPrevSubs_t), true); + CFE_SB_InitMsg(&NoParamCmd, CFE_SB_ValueToMsgId(CFE_SB_SUB_RPT_CTRL_MID), sizeof(CFE_SB_SendPrevSubs_t), true); CFE_SB_SetCmdCode((CFE_SB_MsgPtr_t) &NoParamCmd, CFE_SB_SEND_PREV_SUBS_CC); CFE_SB.CmdPipePktPtr = (CFE_SB_MsgPtr_t) &NoParamCmd; CFE_SB_CreatePipe(&PipeId1, PipeDepth, "TestPipe1"); @@ -2852,7 +2852,7 @@ void Test_SB_Cmds_SubRptOn(void) #endif SB_ResetUnitTest(); - CFE_SB_InitMsg(&NoParamCmd, CFE_SB_ValueToMsgId(CFE_SB_CMD_MID), + CFE_SB_InitMsg(&NoParamCmd, CFE_SB_ValueToMsgId(CFE_SB_SUB_RPT_CTRL_MID), sizeof(NoParamCmd), true); CFE_SB_SetCmdCode((CFE_SB_MsgPtr_t) &NoParamCmd, CFE_SB_ENABLE_SUB_REPORTING_CC); @@ -2890,7 +2890,7 @@ void Test_SB_Cmds_SubRptOff(void) #endif SB_ResetUnitTest(); - CFE_SB_InitMsg(&NoParamCmd, CFE_SB_ValueToMsgId(CFE_SB_CMD_MID), + CFE_SB_InitMsg(&NoParamCmd, CFE_SB_ValueToMsgId(CFE_SB_SUB_RPT_CTRL_MID), sizeof(NoParamCmd), true); CFE_SB_SetCmdCode((CFE_SB_MsgPtr_t) &NoParamCmd, CFE_SB_DISABLE_SUB_REPORTING_CC); @@ -2952,6 +2952,32 @@ void Test_SB_Cmds_UnexpCmdCode(void) TestStat = CFE_FAIL; } + /* Same test for subscription reporting control MID */ + SB_ResetUnitTest(); + CFE_SB_InitMsg(&NoParamCmd, CFE_SB_ValueToMsgId(CFE_SB_SUB_RPT_CTRL_MID), sizeof(NoParamCmd), true); + + /* Use a command code known to be invalid */ + CFE_SB_SetCmdCode((CFE_SB_MsgPtr_t) &NoParamCmd, 99); + CFE_SB.CmdPipePktPtr = (CFE_SB_MsgPtr_t) &NoParamCmd; + CFE_SB_ProcessCmdPipePkt(); + ExpRtn = 1; + ActRtn = UT_GetNumEventsSent(); + + if (ActRtn != ExpRtn) + { + snprintf(cMsg, UT_MAX_MESSAGE_LENGTH, + "Unexpected rtn from UT_GetNumEventsSent, exp=%ld, act=%ld", + (long) ExpRtn, (long) ActRtn); + UT_Text(cMsg); + TestStat = CFE_FAIL; + } + + if (UT_EventIsInHistory(CFE_SB_BAD_CMD_CODE_EID) == false) + { + UT_Text("CFE_SB_BAD_CMD_CODE_EID not sent"); + TestStat = CFE_FAIL; + } + UT_Report(__FILE__, __LINE__, TestStat, "CFE_SB_ProcessCmdPipePkt", "Unexpected command code test"); From 48d7a11394df38c2da6e4156a36ea92016f57749 Mon Sep 17 00:00:00 2001 From: Jacob Hageman Date: Tue, 5 May 2020 07:49:22 -0400 Subject: [PATCH 05/21] Fix #551, Remove duplicate CFE_TIME_Local1HzISR prototype --- fsw/cfe-core/src/time/cfe_time_utils.h | 1 - 1 file changed, 1 deletion(-) diff --git a/fsw/cfe-core/src/time/cfe_time_utils.h b/fsw/cfe-core/src/time/cfe_time_utils.h index 728f69a80..26a0d34d1 100644 --- a/fsw/cfe-core/src/time/cfe_time_utils.h +++ b/fsw/cfe-core/src/time/cfe_time_utils.h @@ -460,7 +460,6 @@ void CFE_TIME_NotifyTimeSynchApps(void); /* ** Function prototypes (local 1Hz interrupt)... */ -void CFE_TIME_Local1HzISR(void); void CFE_TIME_Local1HzTask(void); void CFE_TIME_Local1HzStateMachine(void); void CFE_TIME_Local1HzTimerCallback(uint32 TimerId, void *Arg); From aa94b2ee0e45ab7b26b318934c49f75eed713ad2 Mon Sep 17 00:00:00 2001 From: Chris Knight Date: Tue, 5 May 2020 05:53:52 -0700 Subject: [PATCH 06/21] fix #661 - TBL events update --- fsw/cfe-core/src/inc/cfe_tbl_events.h | 44 +++++++++++++++++++-------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/fsw/cfe-core/src/inc/cfe_tbl_events.h b/fsw/cfe-core/src/inc/cfe_tbl_events.h index 4f4a5f8d6..8906b5d08 100644 --- a/fsw/cfe-core/src/inc/cfe_tbl_events.h +++ b/fsw/cfe-core/src/inc/cfe_tbl_events.h @@ -46,7 +46,7 @@ ** and when you're done adding, set this to the highest EID you used. It may ** be worthwhile to, on occasion, re-number the EID's to put them back in order. */ -#define CFE_TBL_MAX_EID 105 +#define CFE_TBL_MAX_EID 103 /******************* Macro Definitions ***********************/ /* @@ -1064,20 +1064,38 @@ **/ #define CFE_TBL_LOAD_IN_PROGRESS_ERR_EID 100 -/* TODO: document see https://github.com/nasa/cFE/issues/661 */ -#define CFE_TBL_LOAD_SRC_TYPE_ERR_EID 101 - -/* TODO: document see https://github.com/nasa/cFE/issues/661 */ -#define CFE_TBL_LOAD_FILENAME_LONG_ERR_EID 102 - -/* TODO: document see https://github.com/nasa/cFE/issues/661 */ -#define CFE_TBL_LOAD_SHORT_FILE_ERR_EID 103 +/** \brief Filename is too long ('%s' (%lu) > %lu) +** \event Filename is too long ('%s' (%lu) > %lu) +** +** \par Type: ERROR +** +** \par Cause: +** +** The filename provided for the table file is too long (exceeding OS_MAX_PATH_LEN - 1). +**/ +#define CFE_TBL_LOAD_FILENAME_LONG_ERR_EID 101 -/* TODO: document see https://github.com/nasa/cFE/issues/661 */ -#define CFE_TBL_LOAD_TBLNAME_MISMATCH_ERR_EID 104 +/** \brief table name mismatch (exp=%s, tblfilhdr=%s) +** \event table name mismatch (exp=%s, tblfilhdr=%s) +** +** \par Type: ERROR +** +** \par Cause: +** +** The table name in the table file header does not match the specified table name. +**/ +#define CFE_TBL_LOAD_TBLNAME_MISMATCH_ERR_EID 102 -/* TODO: document see https://github.com/nasa/cFE/issues/661 */ -#define CFE_TBL_HANDLE_ACCESS_ERR_EID 105 +/** \brief No access to Tbl handle=%d +** \event No access to Tbl handle=%d +** +** \par Type: ERROR +** +** \par Cause: +** +** The application ID does not have access to the table handle. +**/ +#define CFE_TBL_HANDLE_ACCESS_ERR_EID 103 /** \} */ From 306f28685416eb96a91153c6b3eef3961006a4cd Mon Sep 17 00:00:00 2001 From: Jacob Hageman Date: Tue, 5 May 2020 09:13:42 -0400 Subject: [PATCH 07/21] Fix #519, Deprecate CFS/FS time conversion APIs --- fsw/cfe-core/src/inc/cfe_time.h | 16 ++-- fsw/cfe-core/src/time/cfe_time_api.c | 4 +- fsw/cfe-core/unit-test/time_UT.c | 111 --------------------------- fsw/cfe-core/unit-test/time_UT.h | 21 ----- 4 files changed, 13 insertions(+), 139 deletions(-) diff --git a/fsw/cfe-core/src/inc/cfe_time.h b/fsw/cfe-core/src/inc/cfe_time.h index fa4049d7e..43ff740cd 100644 --- a/fsw/cfe-core/src/inc/cfe_time.h +++ b/fsw/cfe-core/src/inc/cfe_time.h @@ -535,7 +535,7 @@ CFE_TIME_Compare_t CFE_TIME_Compare(CFE_TIME_SysTime_t TimeA, CFE_TIME_SysTime_ ** \return Spacecraft Time (UTC or TAI) corresponding to the specified MET ** ** \sa #CFE_TIME_GetMET, #CFE_TIME_GetMETseconds, #CFE_TIME_GetMETsubsecs, -** #CFE_TIME_Sub2MicroSecs, #CFE_TIME_Micro2SubSecs, #CFE_TIME_CFE2FSSeconds, #CFE_TIME_FS2CFESeconds +** #CFE_TIME_Sub2MicroSecs, #CFE_TIME_Micro2SubSecs ** ******************************************************************************/ CFE_TIME_SysTime_t CFE_TIME_MET2SCTime (CFE_TIME_SysTime_t METTime); @@ -556,7 +556,6 @@ CFE_TIME_SysTime_t CFE_TIME_MET2SCTime (CFE_TIME_SysTime_t METTime); ** \return The equivalent number of microseconds. ** ** \sa #CFE_TIME_MET2SCTime, #CFE_TIME_Micro2SubSecs, -** #CFE_TIME_CFE2FSSeconds, #CFE_TIME_FS2CFESeconds ** ******************************************************************************/ uint32 CFE_TIME_Sub2MicroSecs(uint32 SubSeconds); @@ -579,14 +578,17 @@ uint32 CFE_TIME_Sub2MicroSecs(uint32 SubSeconds); ** value is equal to \c 0xffffffff. ** ** \sa #CFE_TIME_MET2SCTime, #CFE_TIME_Sub2MicroSecs, -** #CFE_TIME_CFE2FSSeconds, #CFE_TIME_FS2CFESeconds ** ******************************************************************************/ uint32 CFE_TIME_Micro2SubSecs(uint32 MicroSeconds); +#ifndef CFE_OMIT_DEPRECATED_6_7 /*****************************************************************************/ /** -** \brief Converts cFE seconds into the File System's seconds +** \brief DEPRECATED: Converts cFE seconds into the File System's seconds +** \deprecated Utilize #CFE_FS_Header_t time fields for the creation +** time in mission format, or syncronize local OS time +** with mission time for use with stat command. ** ** \par Description ** File systems use specific time epochs for their time tagging of files. @@ -612,7 +614,10 @@ uint32 CFE_TIME_CFE2FSSeconds(uint32 SecondsCFE); /*****************************************************************************/ /** -** \brief Converts a file system's seconds into cFE seconds +** \brief DEPRECATED: Converts a file system's seconds into cFE seconds +** \deprecated Utilize #CFE_FS_Header_t time fields for the creation +** time in mission format, or syncronize local OS time +** with mission time for use with stat command. ** ** \par Description ** File systems use specific time epochs for their time tagging of files. @@ -635,6 +640,7 @@ uint32 CFE_TIME_CFE2FSSeconds(uint32 SecondsCFE); ** ******************************************************************************/ uint32 CFE_TIME_FS2CFESeconds(uint32 SecondsFS); +#endif /* CFE_OMIT_DEPRECATED_6_7 */ /**@}*/ /** @defgroup CFEAPITIMEExternSource cFE External Time Source APIs diff --git a/fsw/cfe-core/src/time/cfe_time_api.c b/fsw/cfe-core/src/time/cfe_time_api.c index 9f5a56043..4f03f65c7 100644 --- a/fsw/cfe-core/src/time/cfe_time_api.c +++ b/fsw/cfe-core/src/time/cfe_time_api.c @@ -600,7 +600,7 @@ uint32 CFE_TIME_Micro2SubSecs(uint32 MicroSeconds) } /* End of CFE_TIME_Micro2SubSecs() */ - +#ifndef CFE_OMIT_DEPRECATED_6_7 /* * Function: CFE_TIME_CFE2FSSeconds - See API and header file for details */ @@ -658,7 +658,7 @@ uint32 CFE_TIME_FS2CFESeconds(uint32 SecondsFS) return(SecondsCFE); } /* End of CFE_TIME_FS2CFESeconds() */ - +#endif /* CFE_OMIT_DEPRECATED_6_7 */ /* * Function: CFE_TIME_Print - See API and header file for details diff --git a/fsw/cfe-core/unit-test/time_UT.c b/fsw/cfe-core/unit-test/time_UT.c index 4b8097cc6..55ed0aff7 100644 --- a/fsw/cfe-core/unit-test/time_UT.c +++ b/fsw/cfe-core/unit-test/time_UT.c @@ -210,7 +210,6 @@ void UtTest_Setup(void) UT_ADD_TEST(Test_GetTime); UT_ADD_TEST(Test_TimeOp); UT_ADD_TEST(Test_ConvertTime); - UT_ADD_TEST(Test_ConvertCFEFS); UT_ADD_TEST(Test_Print); UT_ADD_TEST(Test_RegisterSyncCallbackTrue); UT_ADD_TEST(Test_ExternalTone); @@ -1146,116 +1145,6 @@ void Test_ConvertTime(void) "Microseconds exceeds maximum; set maximum subseconds value"); } -/* -** Test function for converting cFE seconds to file system (FS) seconds and -** vice versa -*/ -void Test_ConvertCFEFS(void) -{ - uint32 result; - -#ifdef UT_VERBOSE - UT_Text("Begin Test Convert cFE and FS Seconds\n"); -#endif - - /* Test cFE to FS conversion using 0 for the cFE seconds value */ - UT_InitData(); - - /* Calculate expected result based on macro value */ - if (CFE_MISSION_TIME_FS_FACTOR < 0 && -CFE_MISSION_TIME_FS_FACTOR > 0) - { - result = 0; - } - else - { - result = CFE_MISSION_TIME_FS_FACTOR; - } - - UT_Report(__FILE__, __LINE__, - CFE_TIME_CFE2FSSeconds(0) == result, - "CFE_TIME_CFE2FSSeconds", - "Convert 0 cFE seconds to FS seconds"); - - /* Test cFE to FS conversion using mid-range value for cFE seconds */ - UT_InitData(); - - /* Calculate expected result based on macro value */ - if (CFE_MISSION_TIME_FS_FACTOR < 0 && -CFE_MISSION_TIME_FS_FACTOR > 0xffff) - { - result = 0; - } - else - { - result = CFE_MISSION_TIME_FS_FACTOR + 0xffff; - } - - UT_Report(__FILE__, __LINE__, - CFE_TIME_CFE2FSSeconds(0xffff) == result, - "CFE_TIME_CFE2FSSeconds", - "Convert mid-range cFE seconds to FS seconds"); - - /* Test cFE to FS conversion using the maximum cFE seconds value */ - UT_InitData(); - UT_Report(__FILE__, __LINE__, - CFE_TIME_CFE2FSSeconds(0xffffffff) == - (uint32) (CFE_MISSION_TIME_FS_FACTOR - 1), - "CFE_TIME_CFE2FSSeconds", - "Maximum cFE seconds value"); - - /* Test FS to cFE conversion using 0 for the FS seconds value */ - UT_InitData(); - - if (CFE_MISSION_TIME_FS_FACTOR > 0) - { - result = 0; - } - else - { - result = -(uint32) CFE_MISSION_TIME_FS_FACTOR; - } - - UT_Report(__FILE__, __LINE__, - CFE_TIME_FS2CFESeconds(0) == result, - "CFE_TIME_FS2CFESeconds", - "Convert 0 FS seconds to cFE seconds"); - - /* Test FS to cFE conversion response to a FS seconds value that results - * in a negative cFE time (forces cFE seconds to zero) - */ - UT_InitData(); - UT_Report(__FILE__, __LINE__, - CFE_TIME_FS2CFESeconds(CFE_MISSION_TIME_FS_FACTOR - 1) == 0, - "CFE_TIME_FS2CFESeconds", - "Negative cFE seconds conversion (force to zero)"); - - /* Test FS to cFE conversion using the minimum convertible FS - * seconds value - */ - UT_InitData(); - - if (CFE_MISSION_TIME_FS_FACTOR > (uint32) (CFE_MISSION_TIME_FS_FACTOR + 1)) - { - result = 0; - } - else - { - result = 1; - } - - UT_Report(__FILE__, __LINE__, - CFE_TIME_FS2CFESeconds(CFE_MISSION_TIME_FS_FACTOR + 1) == result, - "CFE_TIME_FS2CFESeconds", - "Minimum convertible FS seconds value"); - - /* Test FS to cFE conversion using the maximum FS seconds value */ - UT_InitData(); - UT_Report(__FILE__, __LINE__, - CFE_TIME_FS2CFESeconds(0xffffffff) == 0xffffffff - - CFE_MISSION_TIME_FS_FACTOR, - "CFE_TIME_FS2CFESeconds", - "Maximum FS seconds value"); -} - /* ** Test function for creating a text string representing the date and time ** diff --git a/fsw/cfe-core/unit-test/time_UT.h b/fsw/cfe-core/unit-test/time_UT.h index dd3af5458..9e1e86572 100644 --- a/fsw/cfe-core/unit-test/time_UT.h +++ b/fsw/cfe-core/unit-test/time_UT.h @@ -153,27 +153,6 @@ void Test_TimeOp(void); ******************************************************************************/ void Test_ConvertTime(void); -/*****************************************************************************/ -/** -** \brief Test function for converting cFE seconds to file system (FS) seconds -** and vice versa -** -** \par Description -** This function tests the function for converting cFE seconds to file -** system (FS) seconds and vice versa. -** -** \par Assumptions, External Events, and Notes: -** None -** -** \returns -** This function does not return a value. -** -** \sa #UT_Text, #UT_InitData, #UT_Report, #CFE_TIME_CFE2FSSeconds, -** \sa #CFE_TIME_FS2CFESeconds -** -******************************************************************************/ -void Test_ConvertCFEFS(void); - /*****************************************************************************/ /** ** \brief Test function for creating a text string representing the date From 8642f8ac5f2b39571e69cba17f1dc55235e07911 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Tue, 5 May 2020 12:05:36 -0400 Subject: [PATCH 08/21] Fix #618, stubs must not depend on real msgid implementation The CFE_SB_GetMsgId/SetMsgId functions, among others, were implemented as replicas of the actual FSW code. This creates a dependency on the actual definition of MsgId used by the mission. This makes the stub and actual stub. Stubs not actually read/write to the message in any way, they just manipulate a local (stored in the UT framework) out-of-band buffer to hold the metadata about the message. This revealed a few other minor issues in test cases where they were depending on values sitting in globals (fixed). --- fsw/cfe-core/unit-test/evs_UT.c | 4 + fsw/cfe-core/unit-test/tbl_UT.c | 8 +- fsw/cfe-core/unit-test/time_UT.c | 4 +- fsw/cfe-core/unit-test/ut_support.c | 3 +- fsw/cfe-core/ut-stubs/ut_sb_stubs.c | 160 +++++++++++++--------------- 5 files changed, 84 insertions(+), 95 deletions(-) diff --git a/fsw/cfe-core/unit-test/evs_UT.c b/fsw/cfe-core/unit-test/evs_UT.c index 7d2259f15..9cbea7bd1 100644 --- a/fsw/cfe-core/unit-test/evs_UT.c +++ b/fsw/cfe-core/unit-test/evs_UT.c @@ -2703,6 +2703,8 @@ void Test_Misc(void) /* Test housekeeping report with log enabled */ UT_InitData(); + CFE_SB_InitMsg((CFE_SB_Msg_t *) &CFE_EVS_GlobalData.EVS_TlmPkt, HK_SnapshotData.MsgId, + sizeof(CFE_EVS_GlobalData.EVS_TlmPkt), false); CFE_EVS_GlobalData.EVS_TlmPkt.Payload.LogEnabled = true; HK_SnapshotData.Count = 0; UT_SetHookFunction(UT_KEY(CFE_SB_SendMsg), UT_SoftwareBusSnapshotHook, &HK_SnapshotData); @@ -2729,6 +2731,8 @@ void Test_Misc(void) /* Test housekeeping report with log disabled */ UT_InitData(); + CFE_SB_InitMsg((CFE_SB_Msg_t *) &CFE_EVS_GlobalData.EVS_TlmPkt, HK_SnapshotData.MsgId, + sizeof(CFE_EVS_GlobalData.EVS_TlmPkt), false); CFE_EVS_GlobalData.EVS_TlmPkt.Payload.LogEnabled = false; HK_SnapshotData.Count = 0; UT_SetHookFunction(UT_KEY(CFE_SB_SendMsg), UT_SoftwareBusSnapshotHook, &HK_SnapshotData); diff --git a/fsw/cfe-core/unit-test/tbl_UT.c b/fsw/cfe-core/unit-test/tbl_UT.c index 4164d8bd4..f1d3e4c2f 100644 --- a/fsw/cfe-core/unit-test/tbl_UT.c +++ b/fsw/cfe-core/unit-test/tbl_UT.c @@ -367,19 +367,17 @@ void Test_CFE_TBL_TaskInit(void) */ void Test_CFE_TBL_InitData(void) { - CFE_SB_MsgId_t MsgIdBuf[2]; - #ifdef UT_VERBOSE UT_Text("Begin Test Init Data\n"); #endif /* This function has only one possible path with no return code */ UT_InitData(); - UT_SetDataBuffer(UT_KEY(CFE_SB_SetMsgId), MsgIdBuf, sizeof(MsgIdBuf), false); CFE_TBL_InitData(); UT_Report(__FILE__, __LINE__, - CFE_SB_MsgId_Equal(MsgIdBuf[1], CFE_SB_ValueToMsgId(CFE_TBL_REG_TLM_MID)) && - UT_GetStubCount(UT_KEY(CFE_SB_SetMsgId)) == 2, + CFE_SB_MsgId_Equal(CFE_SB_GetMsgId((CFE_SB_Msg_t*)&CFE_TBL_TaskData.HkPacket), CFE_SB_ValueToMsgId(CFE_TBL_HK_TLM_MID)) && + CFE_SB_MsgId_Equal(CFE_SB_GetMsgId((CFE_SB_Msg_t*)&CFE_TBL_TaskData.TblRegPacket), CFE_SB_ValueToMsgId(CFE_TBL_REG_TLM_MID)) && + UT_GetStubCount(UT_KEY(CFE_SB_InitMsg)) == 2, "CFE_TBL_SearchCmdHndlrTbl", "Initialize data"); } diff --git a/fsw/cfe-core/unit-test/time_UT.c b/fsw/cfe-core/unit-test/time_UT.c index 4b8097cc6..f8d01854c 100644 --- a/fsw/cfe-core/unit-test/time_UT.c +++ b/fsw/cfe-core/unit-test/time_UT.c @@ -284,7 +284,7 @@ void Test_Init(void) ExpRtn++; CFE_TIME_EarlyInit(); UT_Report(__FILE__, __LINE__, - UT_GetStubCount(UT_KEY(CFE_SB_SetMsgId)) == ExpRtn, + UT_GetStubCount(UT_KEY(CFE_SB_InitMsg)) == ExpRtn, "CFE_TIME_EarlyInit", "Successful"); @@ -1904,6 +1904,8 @@ void Test_PipeCmds(void) /* Test sending the housekeeping telemetry request command */ UT_InitData(); + CFE_SB_InitMsg((CFE_SB_Msg_t *) &CFE_TIME_TaskData.HkPacket, LocalSnapshotData.MsgId, + sizeof(CFE_TIME_TaskData.HkPacket), false); UT_SetHookFunction(UT_KEY(CFE_SB_SendMsg), UT_SoftwareBusSnapshotHook, &LocalSnapshotData); UT_CallTaskPipe(CFE_TIME_TaskPipe, &CmdBuf.message, sizeof(CmdBuf.cmd), UT_TPID_CFE_TIME_SEND_HK); diff --git a/fsw/cfe-core/unit-test/ut_support.c b/fsw/cfe-core/unit-test/ut_support.c index f8fa5d153..56f73725f 100644 --- a/fsw/cfe-core/unit-test/ut_support.c +++ b/fsw/cfe-core/unit-test/ut_support.c @@ -232,8 +232,7 @@ void UT_CallTaskPipe(void (*TaskPipeFunc)(CFE_SB_MsgPtr_t), CFE_SB_MsgPtr_t Msg, * macros (not stubs) to read this info direct from * the buffer. */ - CCSDS_WR_LEN(Msg->Hdr, MsgSize); - CCSDS_WR_SHDR(Msg->Hdr, 1); + CFE_SB_SetTotalMsgLength(Msg, MsgSize); CFE_SB_SetMsgId(Msg, DispatchId.MsgId); CFE_SB_SetCmdCode(Msg, DispatchId.CommandCode); diff --git a/fsw/cfe-core/ut-stubs/ut_sb_stubs.c b/fsw/cfe-core/ut-stubs/ut_sb_stubs.c index 940543303..fe04a804e 100644 --- a/fsw/cfe-core/ut-stubs/ut_sb_stubs.c +++ b/fsw/cfe-core/ut-stubs/ut_sb_stubs.c @@ -36,6 +36,16 @@ #include "cfe.h" #include "utstubs.h" +typedef struct +{ + CFE_SB_MsgId_t MsgId; + uint16 Length; + uint16 CommandCode; + CFE_TIME_SysTime_t TimeStamp; + +} CFE_SB_StubMsg_MetaData_t; + + /* ** Global variables ** @@ -45,6 +55,27 @@ */ CFE_SB_Qos_t CFE_SB_Default_Qos; +static CFE_SB_StubMsg_MetaData_t* CFE_SB_StubMsg_GetMetaData(const CFE_SB_Msg_t *MsgPtr) +{ + CFE_SB_StubMsg_MetaData_t* MetaPtr; + CFE_SB_StubMsg_MetaData_t DefaultMeta; + uint32 MetaSize; + UT_EntryKey_t MsgKey = (UT_EntryKey_t)MsgPtr; + + UT_GetDataBuffer(MsgKey, (void**)&MetaPtr, &MetaSize, NULL); + if (MetaPtr == NULL || MetaSize != sizeof(DefaultMeta)) + { + memset(&DefaultMeta, 0, sizeof(DefaultMeta)); + DefaultMeta.MsgId = CFE_SB_INVALID_MSG_ID; + UT_ResetState(MsgKey); + UT_SetDataBuffer(MsgKey, &DefaultMeta, sizeof(DefaultMeta), true); + + /* Because "allocate copy" is true above, this gets a pointer to the copy */ + UT_GetDataBuffer(MsgKey, (void**)&MetaPtr, &MetaSize, NULL); + } + + return MetaPtr; +} /* ** Functions */ @@ -235,25 +266,26 @@ int32 CFE_SB_GetPipeIdByName(CFE_SB_PipeId_t *PipeIdPtr, const char *PipeName) ** None ** ** \returns -** Returns either the function code from command secondary header or -** CFE_SUCCESS. +** Returns either the function code from command secondary header or 0. ** ******************************************************************************/ uint16 CFE_SB_GetCmdCode(CFE_SB_MsgPtr_t MsgPtr) { int32 status; - CFE_SB_CmdHdr_t *CmdHdrPtr; + uint16 cmdcode = 0; status = UT_DEFAULT_IMPL(CFE_SB_GetCmdCode); - if (status == 0 && CCSDS_RD_TYPE(MsgPtr->Hdr) != CCSDS_TLM) + if (status != 0) + { + cmdcode = status; + } + else { - /* Cast the input pointer to a Cmd Msg pointer */ - CmdHdrPtr = (CFE_SB_CmdHdr_t *)MsgPtr; - status = CCSDS_RD_FC(CmdHdrPtr->Sec); + cmdcode = CFE_SB_StubMsg_GetMetaData(MsgPtr)->CommandCode; } - return status; + return cmdcode; } /*****************************************************************************/ @@ -273,39 +305,13 @@ uint16 CFE_SB_GetCmdCode(CFE_SB_MsgPtr_t MsgPtr) ******************************************************************************/ CFE_SB_MsgId_t CFE_SB_GetMsgId(const CFE_SB_Msg_t *MsgPtr) { - CFE_SB_MsgId_t Result = CFE_SB_INVALID_MSG_ID; - CFE_SB_MsgId_Atom_t MsgIdVal = 0; + CFE_SB_MsgId_t Result; UT_DEFAULT_IMPL(CFE_SB_GetMsgId); if (UT_Stub_CopyToLocal(UT_KEY(CFE_SB_GetMsgId), &Result, sizeof(Result)) < sizeof(Result)) { - -#ifndef MESSAGE_FORMAT_IS_CCSDS_VER_2 - MsgIdVal = CCSDS_RD_SID(MsgPtr->Hdr); -#else - - uint32 SubSystemId; - - MsgIdVal = CCSDS_RD_APID(MsgPtr->Hdr); /* Primary header APID */ - - if ( CCSDS_RD_TYPE(MsgPtr->Hdr) == CCSDS_CMD) - MsgIdVal = MsgIdVal | CFE_SB_CMD_MESSAGE_TYPE; - - /* Add in the SubSystem ID as needed */ - SubSystemId = CCSDS_RD_SUBSYSTEM_ID(MsgPtr->SpacePacket.ApidQ); - MsgIdVal = (MsgIdVal | (SubSystemId << 8)); - -/* Example code to add in the System ID as needed. */ -/* The default is to init this field to the Spacecraft ID but ignore for routing. */ -/* To fully implement this field would require significant SB optimization to avoid */ -/* prohibitively large routing and index tables. */ -/* uint16 SystemId; */ -/* SystemId = CCSDS_RD_SYSTEM_ID(HdrPtr->ApidQ); */ -/* MsgIdVal = (MsgIdVal | (SystemId << 16)) */ -#endif - Result = CFE_SB_ValueToMsgId(MsgIdVal); - + Result = CFE_SB_StubMsg_GetMetaData(MsgPtr)->MsgId; } return Result; @@ -337,11 +343,10 @@ void CFE_SB_InitMsg(void *MsgPtr, if (status >= 0) { - if (UT_Stub_CopyToLocal(UT_KEY(CFE_SB_InitMsg), (uint8*)MsgPtr, Length) < Length) - { - CFE_SB_SetMsgId(MsgPtr, MsgId); - CFE_SB_SetTotalMsgLength(MsgPtr, Length); - } + CFE_SB_StubMsg_GetMetaData(MsgPtr)->MsgId = MsgId; + CFE_SB_StubMsg_GetMetaData(MsgPtr)->Length = Length; + + UT_Stub_CopyToLocal(UT_KEY(CFE_SB_InitMsg), (uint8*)MsgPtr, Length); } } @@ -450,23 +455,12 @@ int32 CFE_SB_SendMsg(CFE_SB_Msg_t *MsgPtr) int32 CFE_SB_SetCmdCode(CFE_SB_MsgPtr_t MsgPtr, uint16 CmdCode) { int32 status; - CFE_SB_CmdHdr_t *CmdHdrPtr; status = UT_DEFAULT_IMPL(CFE_SB_SetCmdCode); - if (status >= 0) + if (status == 0) { - /* If msg type is telemetry, ignore the request */ - if (CCSDS_RD_TYPE(MsgPtr->Hdr) == CCSDS_TLM) - { - status = CFE_SB_WRONG_MSG_TYPE; - } - else - { - /* Cast the input pointer to a Cmd Msg pointer */ - CmdHdrPtr = (CFE_SB_CmdHdr_t *) MsgPtr; - CCSDS_WR_FC(CmdHdrPtr->Sec,CmdCode); - } + CFE_SB_StubMsg_GetMetaData(MsgPtr)->CommandCode = CmdCode; } return status; @@ -489,33 +483,15 @@ int32 CFE_SB_SetCmdCode(CFE_SB_MsgPtr_t MsgPtr, uint16 CmdCode) ******************************************************************************/ void CFE_SB_SetMsgId(CFE_SB_MsgPtr_t MsgPtr, CFE_SB_MsgId_t MsgId) { - UT_DEFAULT_IMPL(CFE_SB_SetMsgId); - UT_Stub_CopyFromLocal(UT_KEY(CFE_SB_SetMsgId), (uint8*)&MsgId, sizeof(MsgId)); - CFE_SB_MsgId_Atom_t MsgIdVal = CFE_SB_MsgIdToValue(MsgId); -#ifndef MESSAGE_FORMAT_IS_CCSDS_VER_2 - CCSDS_WR_SID(MsgPtr->Hdr, MsgIdVal); -#else - CCSDS_WR_VERS(MsgPtr->SpacePacket.Hdr, 1); - - /* Set the stream ID APID in the primary header. */ - CCSDS_WR_APID(MsgPtr->SpacePacket.Hdr, CFE_SB_RD_APID_FROM_MSGID(MsgIdVal) ); - - CCSDS_WR_TYPE(MsgPtr->SpacePacket.Hdr, CFE_SB_RD_TYPE_FROM_MSGID(MsgIdVal) ); - - - CCSDS_CLR_SEC_APIDQ(MsgPtr->SpacePacket.ApidQ); - - CCSDS_WR_EDS_VER(MsgPtr->SpacePacket.ApidQ, 1); - - CCSDS_WR_ENDIAN(MsgPtr->SpacePacket.ApidQ, CFE_PLATFORM_ENDIAN); - - CCSDS_WR_PLAYBACK(MsgPtr->SpacePacket.ApidQ, false); - - CCSDS_WR_SUBSYSTEM_ID(MsgPtr->SpacePacket.ApidQ, CFE_SB_RD_SUBSYS_ID_FROM_MSGID(MsgIdVal)); - - CCSDS_WR_SYSTEM_ID(MsgPtr->SpacePacket.ApidQ, CFE_SPACECRAFT_ID); - -#endif + int32 status; + + status = UT_DEFAULT_IMPL(CFE_SB_SetMsgId); + + if (status == 0) + { + UT_Stub_CopyFromLocal(UT_KEY(CFE_SB_SetMsgId), &MsgId, sizeof(MsgId)); + CFE_SB_StubMsg_GetMetaData(MsgPtr)->MsgId = MsgId; + } } @@ -540,6 +516,11 @@ int32 CFE_SB_SetMsgTime(CFE_SB_MsgPtr_t MsgPtr, CFE_TIME_SysTime_t time) status = UT_DEFAULT_IMPL(CFE_SB_SetMsgTime); + if (status == 0) + { + CFE_SB_StubMsg_GetMetaData(MsgPtr)->TimeStamp = time; + } + return status; } @@ -688,7 +669,7 @@ uint16 CFE_SB_GetTotalMsgLength(const CFE_SB_Msg_t *MsgPtr) } else { - result = CCSDS_RD_LEN(MsgPtr->Hdr); + result = CFE_SB_StubMsg_GetMetaData(MsgPtr)->Length; } return result; } @@ -824,8 +805,7 @@ CFE_TIME_SysTime_t CFE_SB_GetMsgTime(CFE_SB_MsgPtr_t MsgPtr) if (UT_Stub_CopyToLocal(UT_KEY(CFE_SB_GetMsgTime), &TimeFromMsg, sizeof(CFE_TIME_SysTime_t)) != sizeof(CFE_TIME_SysTime_t)) { - TimeFromMsg.Seconds = 123; - TimeFromMsg.Subseconds = 456; + TimeFromMsg = CFE_SB_StubMsg_GetMetaData(MsgPtr)->TimeStamp; } return TimeFromMsg; @@ -869,9 +849,15 @@ void *CFE_SB_GetUserData(CFE_SB_MsgPtr_t MsgPtr) void CFE_SB_SetTotalMsgLength (CFE_SB_MsgPtr_t MsgPtr,uint16 TotalLength) { - UT_DEFAULT_IMPL(CFE_SB_SetTotalMsgLength); - CCSDS_WR_LEN(MsgPtr->Hdr,TotalLength); - UT_Stub_CopyFromLocal(UT_KEY(CFE_SB_SetTotalMsgLength), &TotalLength, sizeof(TotalLength)); + int32 status; + + status = UT_DEFAULT_IMPL(CFE_SB_SetTotalMsgLength); + + if (status == 0) + { + UT_Stub_CopyFromLocal(UT_KEY(CFE_SB_SetTotalMsgLength), &TotalLength, sizeof(TotalLength)); + CFE_SB_StubMsg_GetMetaData(MsgPtr)->Length = TotalLength; + } } uint32 CFE_SB_GetPktType(CFE_SB_MsgId_t MsgId) From d4f62edfad2a29af6d8d9c4714ae52511e4bc058 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Wed, 29 Apr 2020 11:07:24 -0400 Subject: [PATCH 09/21] Fix #411, rework exception handling in CFE Move exception handling to a PSP function. In this approach the CFE only logs data after the event as a background job. Replaces the CFE_ES_ProcessCoreException with a simple notification that causes the ES background job to run, which in turn polls the PSP for logged exceptions and writes entries to the ES ER log. Both the PSP execption scan and the ER log file dump are converted to background jobs. --- cmake/sample_defs/cpu1_platform_cfg.h | 2 +- cmake/target/inc/target_config.h | 13 +- cmake/target/src/target_config.c | 5 +- fsw/cfe-core/src/es/cfe_es_api.c | 136 +----- fsw/cfe-core/src/es/cfe_es_apps.h | 10 + fsw/cfe-core/src/es/cfe_es_backgroundtask.c | 12 + fsw/cfe-core/src/es/cfe_es_erlog.c | 408 +++++++++++++++--- fsw/cfe-core/src/es/cfe_es_log.h | 41 +- fsw/cfe-core/src/es/cfe_es_start.c | 42 +- fsw/cfe-core/src/es/cfe_es_task.c | 94 +--- fsw/cfe-core/src/es/cfe_es_task.h | 26 ++ fsw/cfe-core/src/es/cfe_es_verify.h | 10 - fsw/cfe-core/src/inc/cfe_es.h | 17 +- fsw/cfe-core/src/inc/cfe_es_events.h | 28 +- fsw/cfe-core/src/inc/cfe_evs_msg.h | 1 + .../src/inc/private/cfe_es_erlog_typedef.h | 47 +- .../inc/private/cfe_es_resetdata_typedef.h | 2 +- fsw/cfe-core/unit-test/es_UT.c | 354 ++++++--------- 18 files changed, 674 insertions(+), 574 deletions(-) diff --git a/cmake/sample_defs/cpu1_platform_cfg.h b/cmake/sample_defs/cpu1_platform_cfg.h index 3e85be30c..1a7f3f5bd 100644 --- a/cmake/sample_defs/cpu1_platform_cfg.h +++ b/cmake/sample_defs/cpu1_platform_cfg.h @@ -565,7 +565,7 @@ ** in the error log. Any context information beyond this size will ** be truncated. */ -#define CFE_PLATFORM_ES_ER_LOG_MAX_CONTEXT_SIZE 128 +#define CFE_PLATFORM_ES_ER_LOG_MAX_CONTEXT_SIZE 256 /** diff --git a/cmake/target/inc/target_config.h b/cmake/target/inc/target_config.h index d88d512a5..71c6082cc 100644 --- a/cmake/target/inc/target_config.h +++ b/cmake/target/inc/target_config.h @@ -51,10 +51,15 @@ typedef void (*System_1HzISRFunc_t)(void); /** - * Prototype for exception ISR function implemented in CFE ES + * Prototype for notification function implemented in CFE ES * The PSP should call this when exceptions occur. + * + * NOTE: the PSP must call this routine only from a context where + * it is possible to use OSAL primitives. This means it must _not_ + * be called from an ISR/signal context on systems where these are + * restricted. */ -typedef void (*System_ExceptionFunc_t)(uint32 HostTaskId, const char *ReasonString, const uint32 *ContextPointer, uint32 ContextSize); +typedef void (*System_NotifyFunc_t)(void); /** * Abstract pointer to a module API @@ -87,9 +92,9 @@ typedef const struct System_MainFunc_t SystemMain; /** - * Exception handler function. Called from PSP during exception handling. + * Notification function. Called from PSP after async event handling. */ - System_ExceptionFunc_t SystemExceptionISR; + System_NotifyFunc_t SystemNotify; /* * Sizes of memory segments required by the CFE based on the current config diff --git a/cmake/target/src/target_config.c b/cmake/target/src/target_config.c index 1bde3d10b..f15233450 100644 --- a/cmake/target/src/target_config.c +++ b/cmake/target/src/target_config.c @@ -37,6 +37,7 @@ #include "cfe_platform_cfg.h" #include "cfe_es.h" #include "cfe_time.h" +#include "private/cfe_es_resetdata_typedef.h" #include "cfecfs_version_info.h" #include "cfecfs_build_info.h" @@ -61,7 +62,7 @@ Target_CfeConfigData GLOBAL_CFE_CONFIGDATA = */ .System1HzISR = CFE_TIME_Local1HzISR, .SystemMain = CFE_ES_Main, - .SystemExceptionISR = CFE_ES_ProcessCoreException, + .SystemNotify = CFE_ES_ProcessAsyncEvent, /* * Default values for Startup file. @@ -73,7 +74,7 @@ Target_CfeConfigData GLOBAL_CFE_CONFIGDATA = * Sizes of other memory segments */ .CdsSize = CFE_PLATFORM_ES_CDS_SIZE, - .ResetAreaSize = CFE_PLATFORM_ES_RESET_AREA_SIZE, + .ResetAreaSize = sizeof(CFE_ES_ResetData_t), .UserReservedSize = CFE_PLATFORM_ES_USER_RESERVED_SIZE, .RamDiskSectorSize = CFE_PLATFORM_ES_RAM_DISK_SECTOR_SIZE, diff --git a/fsw/cfe-core/src/es/cfe_es_api.c b/fsw/cfe-core/src/es/cfe_es_api.c index b863f1f69..7c39418ec 100644 --- a/fsw/cfe-core/src/es/cfe_es_api.c +++ b/fsw/cfe-core/src/es/cfe_es_api.c @@ -43,6 +43,7 @@ #include "cfe_es_events.h" #include "cfe_es_cds.h" #include "cfe_es_cds_mempool.h" +#include "cfe_es_task.h" #include "cfe_psp.h" #include "cfe_es_log.h" @@ -96,7 +97,7 @@ int32 CFE_ES_ResetCFE(uint32 ResetType) */ CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, CFE_PSP_RST_SUBTYPE_RESET_COMMAND, - "POWER ON RESET due to max proc resets (Commanded).", NULL,0 ); + "POWER ON RESET due to max proc resets (Commanded)."); /* ** Call the BSP reset routine */ @@ -116,7 +117,7 @@ int32 CFE_ES_ResetCFE(uint32 ResetType) */ CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_PROCESSOR, CFE_PSP_RST_SUBTYPE_RESET_COMMAND, - "PROCESSOR RESET called from CFE_ES_ResetCFE (Commanded).", NULL,0 ); + "PROCESSOR RESET called from CFE_ES_ResetCFE (Commanded)."); /* ** Call the BSP reset routine */ @@ -140,7 +141,7 @@ int32 CFE_ES_ResetCFE(uint32 ResetType) */ CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, CFE_PSP_RST_SUBTYPE_RESET_COMMAND, - "POWERON RESET called from CFE_ES_ResetCFE (Commanded).", NULL,0 ); + "POWERON RESET called from CFE_ES_ResetCFE (Commanded)."); /* ** Call the BSP reset routine @@ -1716,126 +1717,13 @@ void CFE_ES_UnlockSharedData(const char *FunctionName, int32 LineNumber) }/* end CFE_ES_UnlockSharedData */ /****************************************************************************** -** Function: CFE_ES_ProcessCoreException() - See API and header file for details +** Function: CFE_ES_ProcessAsyncEvent() +** +** Purpose: +** Called by the PSP to notify CFE ES that an asynchronous event occurred. */ -void CFE_ES_ProcessCoreException(uint32 HostTaskId, const char *ReasonString, - const uint32 *ContextPointer, uint32 ContextSize) +void CFE_ES_ProcessAsyncEvent(void) { - uint32 i; - int32 Status; - OS_task_prop_t TaskProp; - CFE_ES_TaskInfo_t EsTaskInfo; - uint32 FoundExceptionTask = 0; - uint32 ExceptionTaskID = 0; - - /* - ** If a loadable cFE Application caused the reset and it's - ** exception action is set to Restart the App rather than cause a - ** processor reset, then just reset the App. - */ - - /* - ** We have the Host Task Id ( vxWorks, RTEMS, etc ). Search - ** the OSAPI to see if a match can be found. - */ - for ( i = 0; i < OS_MAX_TASKS; i++ ) - { - if (CFE_ES_Global.TaskTable[i].RecordUsed == true) - { - ExceptionTaskID = CFE_ES_Global.TaskTable[i].TaskId; - Status = OS_TaskGetInfo (ExceptionTaskID, &TaskProp); - - if ( Status == OS_SUCCESS && TaskProp.OStask_id == HostTaskId ) - { - FoundExceptionTask = 1; - break; - } - } - } - - /* - ** If the Task is found in the OS, see if the cFE App ID associated with it can be found. - */ - if ( FoundExceptionTask == 1 ) - { - Status = CFE_ES_GetTaskInfo( &EsTaskInfo, ExceptionTaskID ); - /* - ** The App ID was found, now see if the ExceptionAction is set for a reset - */ - if ( Status == CFE_SUCCESS ) - { - if ( CFE_ES_Global.AppTable[EsTaskInfo.AppId].StartParams.ExceptionAction == CFE_ES_ExceptionAction_RESTART_APP ) - { - - /* - ** Log the Application reset - */ - CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_ES_APP_RESTART, - CFE_PSP_RST_SUBTYPE_EXCEPTION, (char *)ReasonString, - ContextPointer, ContextSize ); - - /* - ** Finally restart the App! This call is just a request - ** to ES. - */ - CFE_ES_RestartApp(EsTaskInfo.AppId ); - - /* - ** Return to avoid the Processor Restart Logic - */ - return; - - } /* end if ExceptionAction */ - - } /* end if */ - - } /* End if FoundExceptionTask */ - - /* - ** If we made it here, which means that we need to do a processor reset - */ - - /* - ** Before doing a Processor reset, check to see - ** if the maximum number has been exceeded - */ - if ( CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount >= - CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount ) - { - /* - ** Log the reset in the ER Log. The log will be wiped out, but it's good to have - ** the entry just in case something fails. - */ - CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, - CFE_PSP_RST_SUBTYPE_EXCEPTION, (char *)ReasonString, - ContextPointer, ContextSize ); - - /* - ** Call the BSP reset routine to do a Poweron Reset - */ - CFE_PSP_Restart(CFE_PSP_RST_TYPE_POWERON); - - } - else /* Do a processor reset */ - { - /* - ** Update the reset variables - */ - CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount++; - CFE_ES_ResetDataPtr->ResetVars.ES_CausedReset = true; - - /* - ** Log the reset in the ER Log - */ - CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_PROCESSOR, - CFE_PSP_RST_SUBTYPE_EXCEPTION, (char *)ReasonString, - ContextPointer, ContextSize ); - - /* - ** Need to do a processor reset - */ - CFE_PSP_Restart(CFE_PSP_RST_TYPE_PROCESSOR); - - } /* end if */ - -} /* End of CFE_ES_ProcessCoreException */ + /* This just wakes up the background task to log/handle the event. */ + CFE_ES_BackgroundWakeup(); +} diff --git a/fsw/cfe-core/src/es/cfe_es_apps.h b/fsw/cfe-core/src/es/cfe_es_apps.h index b9a2254c4..19ec02890 100644 --- a/fsw/cfe-core/src/es/cfe_es_apps.h +++ b/fsw/cfe-core/src/es/cfe_es_apps.h @@ -198,6 +198,16 @@ int32 CFE_ES_AppDumpAllInfo(void); */ bool CFE_ES_RunAppTableScan(uint32 ElapsedTime, void *Arg); +/* +** Scan for new exceptions stored in the PSP +*/ +bool CFE_ES_RunExceptionScan(uint32 ElapsedTime, void *Arg); + +/* +** Check if ER log dump request is pending +*/ +bool CFE_ES_RunERLogDump(uint32 ElapsedTime, void *Arg); + /* ** Perform the requested control action for an application */ diff --git a/fsw/cfe-core/src/es/cfe_es_backgroundtask.c b/fsw/cfe-core/src/es/cfe_es_backgroundtask.c index 5582fa8da..5b874679e 100644 --- a/fsw/cfe-core/src/es/cfe_es_backgroundtask.c +++ b/fsw/cfe-core/src/es/cfe_es_backgroundtask.c @@ -82,6 +82,18 @@ const CFE_ES_BackgroundJobEntry_t CFE_ES_BACKGROUND_JOB_TABLE[] = .JobArg = &CFE_ES_TaskData.BackgroundPerfDumpState, .ActivePeriod = CFE_PLATFORM_ES_PERF_CHILD_MS_DELAY, .IdlePeriod = CFE_PLATFORM_ES_PERF_CHILD_MS_DELAY * 1000 + }, + { /* Check for exceptions stored in the PSP */ + .RunFunc = CFE_ES_RunExceptionScan, + .JobArg = NULL, + .ActivePeriod = CFE_PLATFORM_ES_APP_SCAN_RATE, + .IdlePeriod = CFE_PLATFORM_ES_APP_SCAN_RATE + }, + { /* Check for ER log write requests */ + .RunFunc = CFE_ES_RunERLogDump, + .JobArg = &CFE_ES_TaskData.BackgroundERLogDumpState, + .ActivePeriod = CFE_PLATFORM_ES_APP_SCAN_RATE, + .IdlePeriod = CFE_PLATFORM_ES_APP_SCAN_RATE } }; diff --git a/fsw/cfe-core/src/es/cfe_es_erlog.c b/fsw/cfe-core/src/es/cfe_es_erlog.c index 51ca03105..d4bf207d5 100644 --- a/fsw/cfe-core/src/es/cfe_es_erlog.c +++ b/fsw/cfe-core/src/es/cfe_es_erlog.c @@ -43,36 +43,49 @@ #include "cfe_es_apps.h" #include "cfe_es_global.h" #include "cfe_es_log.h" +#include "cfe_es_task.h" #include "cfe_psp.h" #include #include #include +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* - * Confirm the size of the error log context buffer is at least what the user asked for. - * - * This is to catch errors such as if the CFE_PLATFORM_ES_ER_LOG_MAX_CONTEXT_SIZE was set to a value - * that is _not_ a multiple of sizeof(uint32) -- in this case the final size of the context - * buffer would end up being less than what the macro was set to. - */ -CompileTimeAssert(sizeof(CFE_ES_ResetDataPtr->ERLog[0].Context) == CFE_PLATFORM_ES_ER_LOG_MAX_CONTEXT_SIZE, CfeEsErLogContextSizeError); - - -/* -** Function: CFE_ES_WriteToERLog +** Function: CFE_ES_WriteToERLogWithContext ** ** Purpose: Create an entry in the ES Exception and Reset Log. +** This log API accepts extra context information (AppID and ContextID) +** and is used when the app/task invoking this API is not the same app +** as where the event occurred. ** */ -int32 CFE_ES_WriteToERLog( uint32 EntryType, uint32 ResetType, uint32 ResetSubtype, - const char *Description, const uint32 *Context, uint32 ContextSize ) +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +int32 CFE_ES_WriteToERLogWithContext( CFE_ES_LogEntryType_Enum_t EntryType, uint32 ResetType, uint32 ResetSubtype, + const char *Description, uint32 AppId, uint32 PspContextId) { uint32 LogIdx; + CFE_ES_ERLog_MetaData_t *EntryPtr; + CFE_TIME_SysTime_t PendingTime; /* - ** Code - */ + * Snapshot the time before locking (different subsystem) + */ + PendingTime = CFE_TIME_GetTime(); + + /* + * Ensure that description string is not NULL. + */ + if ( Description == NULL) + { + Description = "No Description String Given."; + } + + /* + * This routine needs to lock in case it is called + * from concurrent threads + */ + CFE_ES_LockSharedData(__func__,__LINE__); /* ** Try to clean up an invalid ER log index variable. @@ -96,89 +109,342 @@ int32 CFE_ES_WriteToERLog( uint32 EntryType, uint32 ResetType, uint32 ResetSu /* ** Clear out the log entry we are about to use. */ - memset( &(CFE_ES_ResetDataPtr->ERLog[LogIdx]), 0, - sizeof (CFE_ES_ERLog_t)); + EntryPtr = &CFE_ES_ResetDataPtr->ERLog[LogIdx]; + memset(EntryPtr, 0, sizeof (*EntryPtr)); /* ** Fill out the log fields */ - CFE_ES_ResetDataPtr->ERLog[LogIdx].LogEntryType = EntryType; - CFE_ES_ResetDataPtr->ERLog[LogIdx].ResetType = ResetType; - CFE_ES_ResetDataPtr->ERLog[LogIdx].ResetSubtype = ResetSubtype; - CFE_ES_ResetDataPtr->ERLog[LogIdx].BootSource = CFE_ES_ResetDataPtr->ResetVars.BootSource; - CFE_ES_ResetDataPtr->ERLog[LogIdx].ProcessorResetCount = + EntryPtr->BaseInfo.LogEntryType = EntryType; + EntryPtr->BaseInfo.ResetType = ResetType; + EntryPtr->BaseInfo.ResetSubtype = ResetSubtype; + EntryPtr->BaseInfo.BootSource = CFE_ES_ResetDataPtr->ResetVars.BootSource; + EntryPtr->BaseInfo.ProcessorResetCount = CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount; - CFE_ES_ResetDataPtr->ERLog[LogIdx].MaxProcessorResetCount = + EntryPtr->BaseInfo.MaxProcessorResetCount = CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount; /* ** Copy the ES Reset variables to the log (before they are modified by the log entry). */ - memcpy(&(CFE_ES_ResetDataPtr->ERLog[LogIdx].DebugVars), - (void *)&(CFE_ES_Global.DebugVars), - sizeof(CFE_ES_DebugVariables_t )); + memcpy(&EntryPtr->BaseInfo.DebugVars, &CFE_ES_Global.DebugVars, + sizeof(EntryPtr->BaseInfo.DebugVars)); /* - ** Time Stamp the log entry with the system time + ** Time Stamp the log entry with the system time */ - CFE_ES_ResetDataPtr->ERLog[LogIdx].TimeCode = CFE_TIME_GetTime(); + EntryPtr->BaseInfo.TimeCode = PendingTime; /* ** Copy the Description string to the log. */ - if ( Description == NULL) - { - strncpy(CFE_ES_ResetDataPtr->ERLog[LogIdx].Description, "No Description String Given.", 80); - } - else - { - strncpy(CFE_ES_ResetDataPtr->ERLog[LogIdx].Description, Description, 80); - } + strncpy(EntryPtr->BaseInfo.Description, Description, sizeof(EntryPtr->BaseInfo.Description)); /* - ** In the case of an exception, copy the processor context data to the log. - */ - if (Context != NULL && ContextSize > 0) - { - /* - ** Copy the processor context data (i.e. register dump). Make sure that - ** the passed-in context_size is not greater than the declared size in - ** the ER Log log entry. - */ - if ( ContextSize <= CFE_PLATFORM_ES_ER_LOG_MAX_CONTEXT_SIZE ) - { - memcpy ( (CFE_ES_ResetDataPtr->ERLog[LogIdx].Context), - (void *)Context, - ContextSize); - } - else - { - memcpy ( (CFE_ES_ResetDataPtr->ERLog[LogIdx].Context), - (void *)Context, - CFE_PLATFORM_ES_ER_LOG_MAX_CONTEXT_SIZE); - } - /* - ** Indicate that context is valid. - ** Using the original context size (not the truncated size) so it will be - ** evident if the context information was truncated. - */ - CFE_ES_ResetDataPtr->ERLog[LogIdx].ContextSize = ContextSize; - } - else - { - /* - ** Context is not valid - */ - CFE_ES_ResetDataPtr->ERLog[LogIdx].ContextSize = 0; - } /* end if */ + * Store the context info (if any) + */ + EntryPtr->AppID = AppId; + EntryPtr->PspContextId = PspContextId; /* ** Increment the number of ER log entries made */ CFE_ES_ResetDataPtr->ERLogEntries++; + /* + * Shared data update is complete + */ + CFE_ES_UnlockSharedData(__func__,__LINE__); + return(CFE_SUCCESS); + +} /* End of CFE_ES_WriteToERLogWithContext() */ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* +** Function: CFE_ES_WriteToERLog +** +** Purpose: Create an entry in the ES Exception and Reset Log. +** This log API is simplified for cases which do not have a separate context +** +*/ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +int32 CFE_ES_WriteToERLog( CFE_ES_LogEntryType_Enum_t EntryType, uint32 ResetType, uint32 ResetSubtype, + const char *Description) +{ + /* passing 0xFFFFFFFF as the appid avoids confusion with actual appid 0 */ + return CFE_ES_WriteToERLogWithContext(EntryType, ResetType, ResetSubtype, + Description, 0xFFFFFFFF, CFE_ES_ERLOG_NO_CONTEXT); } /* End of CFE_ES_WriteToERLog() */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* Function: CFE_ES_RunERLogDump() */ +/* */ +/* Purpose: */ +/* Write exception & reset log to a file. */ +/* */ +/* Implemented as an ES background job, but the entire file write is done */ +/* in a single invocation, as the file is expected to be relatively small. */ +/* */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +bool CFE_ES_RunERLogDump(uint32 ElapsedTime, void *Arg) +{ + CFE_ES_BackgroundLogDumpGlobal_t *State = (CFE_ES_BackgroundLogDumpGlobal_t *)Arg; + int32 WriteStat; + int32 PspStatus; + CFE_FS_Header_t FileHdr; + CFE_ES_ERLog_FileEntry_t FileEntry; + CFE_ES_ERLog_MetaData_t *EntryPtr; + uint32 FileSize; + uint32 i; + int32 fd; + + + if (!State->IsPending) + { + return false; + } + + FileSize = 0; + fd = OS_creat(State->DataFileName, OS_WRITE_ONLY); + if(fd < 0) + { + CFE_EVS_SendEvent(CFE_ES_ERLOG2_ERR_EID,CFE_EVS_EventType_ERROR, + "Error creating file %s, RC = 0x%08X", + State->DataFileName, (unsigned int)fd); + } + else + { + CFE_FS_InitHeader(&FileHdr, CFE_ES_ER_LOG_DESC, CFE_FS_SubType_ES_ERLOG); + + /* write the cFE header to the file */ + WriteStat = CFE_FS_WriteHeader(fd, &FileHdr); + if(WriteStat != sizeof(CFE_FS_Header_t)) + { + CFE_ES_FileWriteByteCntErr(State->DataFileName,sizeof(CFE_FS_Header_t),WriteStat); + } + else + { + FileSize += WriteStat; + + /* write a single ER log entry on each pass */ + for(i=0;iERLog[i]; + + /* The basic info comes directly from the ES log */ + FileEntry.BaseInfo = EntryPtr->BaseInfo; + + /* + * The context info, if available, comes from the PSP. + * This returns the actual size of the context info, or <0 on error. + */ + PspStatus = CFE_PSP_Exception_CopyContext(EntryPtr->PspContextId, &FileEntry.Context, sizeof(FileEntry.Context)); + if (PspStatus > 0) + { + FileEntry.ContextSize = PspStatus; + } + else + { + /* + * errors here are OK - just means there is no context available. + * Record a size of 0 in the log file. + */ + FileEntry.ContextSize = 0; + } + + /* + * any unused context space should be cleared. + * + * This is for binary compatibility with historical log files, where a fixed amount + * of space is given per-entry, regardless of the actual size. + */ + if (FileEntry.ContextSize < sizeof(FileEntry.Context)) + { + memset(&FileEntry.Context[FileEntry.ContextSize], 0, + sizeof(FileEntry.Context) - FileEntry.ContextSize); + } + + /* + * Now write to file + */ + WriteStat = OS_write(fd,&FileEntry,sizeof(FileEntry)); + + if(WriteStat != sizeof(FileEntry)) + { + CFE_ES_FileWriteByteCntErr(State->DataFileName,sizeof(FileEntry),WriteStat); + break; + }/* end if */ + + FileSize += WriteStat; + + } /* end for */ + + } /* end if */ + + OS_close(fd); + + CFE_EVS_SendEvent(CFE_ES_ERLOG2_EID, CFE_EVS_EventType_DEBUG, + "%s written:Size=%lu",State->DataFileName,(unsigned long)FileSize); + + } /* end if */ + + /* + * Always clear the "pending" flag whether successful or not. + * If unsuccessful, an operator needs to investigate the error and re-issue command. + */ + State->IsPending = false; + + return false; +}/* end CFE_ES_RunERLogDump */ + + +/* +**--------------------------------------------------------------------------------------- +** Name: CFE_ES_RunExceptionScan +** +** Purpose: This function pools the PSP to check if any exceptions have been logged +** since the last background cycle. If an exception is present, retreive +** the details, add it to the ER log, and trigger the action (e.g. app restart). +**--------------------------------------------------------------------------------------- +*/ +bool CFE_ES_RunExceptionScan(uint32 ElapsedTime, void *Arg) +{ + int32 Status; + uint32 PspContextId; + char ReasonString[CFE_ES_ERLOG_DESCRIPTION_MAX_LENGTH]; + CFE_ES_TaskInfo_t EsTaskInfo; + uint32 ExceptionTaskID; + uint32 ResetType; + CFE_ES_LogEntryType_Enum_t LogType; + + if (CFE_PSP_Exception_GetCount() == 0) + { + /* no exceptions pending, nothing to do */ + return false; + } + + /* + * Note a reset type of 0 is not defined by the PSP - + * the real values are all nonzero + */ + ResetType = 0; + memset(&EsTaskInfo, 0, sizeof(EsTaskInfo)); + Status = CFE_PSP_Exception_GetSummary(&PspContextId, &ExceptionTaskID, ReasonString, sizeof(ReasonString)); + if (Status != CFE_PSP_SUCCESS) + { + /* reason string is not available - populate with something for the log */ + snprintf(ReasonString, sizeof(ReasonString), "Unknown - CFE_PSP_ExceptionGetSummary() error %ld", (long)Status); + PspContextId = 0; + ExceptionTaskID = 0; + } /* end if */ + + /* + * Note that writes to the ES ER log actually do not get propagated to the debug console. + * so by writing to SysLog here it becomes visible in both places. + */ + CFE_ES_WriteToSysLog("ExceptionID 0x%lx in TaskID %lu: %s\n", + (unsigned long)PspContextId, (unsigned long)ExceptionTaskID, ReasonString); + + /* + * If task ID is 0, this means it was a system level exception and + * not associated with a specific task. + * + * Otherwise, if it was related to a task, determine the associated AppID + * so the exception action can be checked. + */ + if (ExceptionTaskID != 0) + { + Status = CFE_ES_GetTaskInfo( &EsTaskInfo, ExceptionTaskID ); + + /* + * The App ID was found, now see if the ExceptionAction is set for a reset + */ + if (Status == CFE_SUCCESS && + CFE_ES_Global.AppTable[EsTaskInfo.AppId].StartParams.ExceptionAction == CFE_ES_ExceptionAction_RESTART_APP) + { + /* + * Log the Application reset + */ + ResetType = CFE_ES_APP_RESTART; + } + } + + do + { + /* + * If no disposition is identified yet, then trigger a PSP reset. + * Need to determine if a processor or poweron reset is needed. + */ + if (ResetType == 0) + { + if ( CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount >= + CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount ) + { + CFE_ES_WriteToSysLog("Maximum Processor Reset count reached (%u)", + (unsigned int)CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount); + + ResetType = CFE_PSP_RST_TYPE_POWERON; + } + else + { + CFE_ES_WriteToSysLog("Processor Reset count not reached (%u/%u)", + (unsigned int)CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount, + (unsigned int)CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount); + + + /* + ** Update the reset variables + */ + CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount++; + CFE_ES_ResetDataPtr->ResetVars.ES_CausedReset = true; + + ResetType = CFE_PSP_RST_TYPE_PROCESSOR; + } + } + + if (ResetType == CFE_ES_APP_RESTART) + { + LogType = CFE_ES_LogEntryType_APPLICATION; + } + else + { + LogType = CFE_ES_LogEntryType_CORE; + } + + + CFE_ES_WriteToERLogWithContext(LogType, ResetType, + CFE_PSP_RST_SUBTYPE_EXCEPTION, ReasonString, + EsTaskInfo.AppId, + PspContextId); + + if (ResetType == CFE_ES_APP_RESTART) + { + /* + * Restart the App. This call is just a request + * to ES, but the request could fail. If that happens, + * proceed to a processor reset. + */ + Status = CFE_ES_RestartApp(EsTaskInfo.AppId); + if (Status != CFE_SUCCESS) + { + ResetType = 0; + snprintf(ReasonString, sizeof(ReasonString), "App Restart Failed"); + } + } + else + { + /* normally this will not return */ + CFE_PSP_Restart(ResetType); + } + } + while(ResetType == 0); + + + return true; /* returning true because there was an exception to deal with */ +} + + + /* end of file */ diff --git a/fsw/cfe-core/src/es/cfe_es_log.h b/fsw/cfe-core/src/es/cfe_es_log.h index c595be3e7..f02bc902a 100644 --- a/fsw/cfe-core/src/es/cfe_es_log.h +++ b/fsw/cfe-core/src/es/cfe_es_log.h @@ -108,6 +108,14 @@ } +/** + * \brief Indicates no context information Error Logs + * + * For use with the CFE_ES_WriteToERLog() function when no context + * information is available. + */ +#define CFE_ES_ERLOG_NO_CONTEXT (0) + /* ** Type Definitions */ @@ -328,8 +336,35 @@ void CFE_ES_PerfLogDump(void); /* ** Exception and Reset Log API */ -int32 CFE_ES_WriteToERLog( uint32 EntryType, uint32 ResetType, uint32 ResetSubtype, - const char *Description, const uint32 *Context, uint32 ContextSize ); -int32 CFE_ES_ERLogDump(const char *Filename); + +/** + * \brief Create an entry in the ES Exception and Reset Log. + * + * The exception and reset log is used to track significant system-level events and anomalies + * for later analysis. + * + * \param EntryType Whether the event is relevant to the CORE or an APPLICATION (#CFE_ES_LogEntryType_Enum_t) + * \param ResetType The type of the last reset + * \param ResetSubType The subtype of the last reset + * \param Description A summary of the event + * + * \return CFE_SUCCESS if successful, or an appropriate error code from cfe_error.h + */ +int32 CFE_ES_WriteToERLog( CFE_ES_LogEntryType_Enum_t EntryType, uint32 ResetType, uint32 ResetSubtype, + const char *Description); + + +/** + * \copydoc CFE_ES_WriteToERLog() + * + * This log API accepts extra context information (AppID and ContextID) + * and is used when the app/task invoking this API is not the same app + * as where the event occurred. + * + * \param AppId The Application ID associated with the task that caused the exception + * \param PspContextId Identifier of extended context info stored in the PSP (if available) + */ +int32 CFE_ES_WriteToERLogWithContext( CFE_ES_LogEntryType_Enum_t EntryType, uint32 ResetType, uint32 ResetSubtype, + const char *Description, uint32 AppId, uint32 PspContextId); #endif /* _cfe_es_log_ */ diff --git a/fsw/cfe-core/src/es/cfe_es_start.c b/fsw/cfe-core/src/es/cfe_es_start.c index e1ccc24a9..5d73fc64c 100644 --- a/fsw/cfe-core/src/es/cfe_es_start.c +++ b/fsw/cfe-core/src/es/cfe_es_start.c @@ -91,20 +91,6 @@ void CFE_ES_Main(uint32 StartType, uint32 StartSubtype, uint32 ModeId, const cha */ CFE_ES_Global.SystemState = CFE_ES_SystemState_EARLY_INIT; - /* - ** Initialize the Reset variables. This call is required - ** Before most of the ES functions can be used including the - ** ES System log. - */ - CFE_ES_SetupResetVariables(StartType, StartSubtype, ModeId); - - /* - ** Initialize the Logic Perf variables - ** Because this is in the ES Reset area, it must be called after - ** CFE_ES_SetupResetVariables. - */ - CFE_ES_SetupPerfVariables(StartType); - /* ** Create the ES Shared Data Mutex ** This must be done before ANY calls to CFE_ES_WriteToSysLog(), since this uses the mutex @@ -131,6 +117,20 @@ void CFE_ES_Main(uint32 StartType, uint32 StartSubtype, uint32 ModeId, const cha return; } /* end if */ + /* + ** Initialize the Reset variables. This call is required + ** Before most of the ES functions can be used including the + ** ES System log. + */ + CFE_ES_SetupResetVariables(StartType, StartSubtype, ModeId); + + /* + ** Initialize the Logic Perf variables + ** Because this is in the ES Reset area, it must be called after + ** CFE_ES_SetupResetVariables. + */ + CFE_ES_SetupPerfVariables(StartType); + /* ** Also Create the ES Performance Data Mutex ** This is to separately protect against concurrent writes to the global performance log data @@ -366,19 +366,19 @@ void CFE_ES_SetupResetVariables(uint32 StartType, uint32 StartSubtype, uint32 Bo { CFE_ES_SysLogWrite_Unsync("POWER ON RESET due to Power Cycle (Power Cycle).\n"); CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, StartSubtype, - "POWER ON RESET due to Power Cycle (Power Cycle)", NULL,0 ); + "POWER ON RESET due to Power Cycle (Power Cycle)"); } else if ( StartSubtype == CFE_PSP_RST_SUBTYPE_HW_SPECIAL_COMMAND ) { CFE_ES_SysLogWrite_Unsync("POWER ON RESET due to HW Special Cmd (Hw Spec Cmd).\n"); CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, StartSubtype, - "POWER ON RESET due to HW Special Cmd (Hw Spec Cmd)", NULL,0 ); + "POWER ON RESET due to HW Special Cmd (Hw Spec Cmd)"); } else { CFE_ES_SysLogWrite_Unsync("POWER ON RESET due to other cause (See Subtype).\n"); CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, StartSubtype, - "POWER ON RESET due to other cause (See Subtype)", NULL,0 ); + "POWER ON RESET due to other cause (See Subtype)"); } /* @@ -418,7 +418,7 @@ void CFE_ES_SetupResetVariables(uint32 StartType, uint32 StartSubtype, uint32 Bo ** the entry just in case something fails. */ CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, StartSubtype, - "POWER ON RESET due to max proc resets (HW Spec Cmd).", NULL,0 ); + "POWER ON RESET due to max proc resets (HW Spec Cmd)."); } else { @@ -430,7 +430,7 @@ void CFE_ES_SetupResetVariables(uint32 StartType, uint32 StartSubtype, uint32 Bo ** the entry just in case something fails. */ CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, StartSubtype, - "POWER ON RESET due to max proc resets (Watchdog).", NULL,0 ); + "POWER ON RESET due to max proc resets (Watchdog)."); } /* ** Call the BSP reset routine @@ -454,7 +454,7 @@ void CFE_ES_SetupResetVariables(uint32 StartType, uint32 StartSubtype, uint32 Bo ** Log the watchdog reset */ CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_PROCESSOR, StartSubtype, - "PROCESSOR RESET due to Hardware Special Command (Hw Spec Cmd).", NULL,0 ); + "PROCESSOR RESET due to Hardware Special Command (Hw Spec Cmd)."); } else @@ -466,7 +466,7 @@ void CFE_ES_SetupResetVariables(uint32 StartType, uint32 StartSubtype, uint32 Bo ** Log the watchdog reset */ CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_PROCESSOR, StartSubtype, - "PROCESSOR RESET due to Watchdog (Watchdog).", NULL,0 ); + "PROCESSOR RESET due to Watchdog (Watchdog)."); } diff --git a/fsw/cfe-core/src/es/cfe_es_task.c b/fsw/cfe-core/src/es/cfe_es_task.c index 2f750536e..303ccfb2c 100644 --- a/fsw/cfe-core/src/es/cfe_es_task.c +++ b/fsw/cfe-core/src/es/cfe_es_task.c @@ -1589,94 +1589,30 @@ int32 CFE_ES_ClearERLogCmd(const CFE_ES_ClearERLog_t *data) int32 CFE_ES_WriteERLogCmd(const CFE_ES_WriteERLog_t *data) { const CFE_ES_FileNameCmd_Payload_t *CmdPtr = &data->Payload; - int32 Stat; - char LogFilename[OS_MAX_PATH_LEN]; - CFE_SB_MessageStringGet(LogFilename, (char *)CmdPtr->FileName, - CFE_PLATFORM_ES_DEFAULT_ER_LOG_FILE, OS_MAX_PATH_LEN, sizeof(CmdPtr->FileName)); - - Stat = CFE_ES_ERLogDump(LogFilename); - - if(Stat == CFE_SUCCESS) + if (CFE_ES_TaskData.BackgroundERLogDumpState.IsPending) { - CFE_ES_TaskData.CommandCounter++; + CFE_EVS_SendEvent(CFE_ES_ERLOG_PENDING_ERR_EID,CFE_EVS_EventType_ERROR, + "Error log write to file %s already in progress", + CFE_ES_TaskData.BackgroundERLogDumpState.DataFileName); + + /* background dump already running, consider this an error */ + CFE_ES_TaskData.CommandErrorCounter++; } else { - CFE_ES_TaskData.CommandErrorCounter++; - }/* end if */ - - return CFE_SUCCESS; -}/* end CFE_ES_WriteERLogCmd */ - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* */ -/* CFE_ES_ERLogDump() -- Write exception & reset log to a file. */ -/* */ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -int32 CFE_ES_ERLogDump(const char *Filename) -{ - - int32 fd; - int32 WriteStat,BspStat; - uint32 FileSize,i,ResetAreaSize; - CFE_FS_Header_t FileHdr; - cpuaddr ResetDataAddr; - - fd = OS_creat(Filename, OS_WRITE_ONLY); - if(fd < 0) - { - CFE_EVS_SendEvent(CFE_ES_ERLOG2_ERR_EID,CFE_EVS_EventType_ERROR, - "Error creating file %s, RC = 0x%08X", - Filename,(unsigned int)fd); - return CFE_ES_FILE_IO_ERR; - }/* end if */ - - CFE_FS_InitHeader(&FileHdr, CFE_ES_ER_LOG_DESC, CFE_FS_SubType_ES_ERLOG); - - /* write the cFE header to the file */ - WriteStat = CFE_FS_WriteHeader(fd, &FileHdr); - if(WriteStat != sizeof(CFE_FS_Header_t)) - { - CFE_ES_FileWriteByteCntErr(Filename,sizeof(CFE_FS_Header_t),WriteStat); - OS_close(fd); - return CFE_ES_FILE_IO_ERR; - }/* end if */ - FileSize = WriteStat; + CFE_SB_MessageStringGet(CFE_ES_TaskData.BackgroundERLogDumpState.DataFileName, (char *)CmdPtr->FileName, + CFE_PLATFORM_ES_DEFAULT_ER_LOG_FILE, + sizeof(CFE_ES_TaskData.BackgroundERLogDumpState.DataFileName), sizeof(CmdPtr->FileName)); - /* Get the pointer to the Reset Log from the BSP */ - BspStat = CFE_PSP_GetResetArea (&ResetDataAddr, &ResetAreaSize); - if(BspStat != CFE_PSP_SUCCESS) - { - CFE_EVS_SendEvent(CFE_ES_RST_ACCESS_EID, CFE_EVS_EventType_ERROR, - "Error accessing ER Log,%s not written. RC = 0x%08X",Filename,(unsigned int)BspStat); - OS_close(fd); - return CFE_ES_RST_ACCESS_ERR; - }/* end if */ - - /* write a single ER log entry on each pass */ - for(i=0;i UINT32_MAX - #error CFE_PLATFORM_ES_RESET_AREA_SIZE cannot be greater than UINT32_MAX (4 Gigabytes)! -#endif - /* ** The size of a command to the OS that lies under the cFE */ diff --git a/fsw/cfe-core/src/inc/cfe_es.h b/fsw/cfe-core/src/inc/cfe_es.h index 4f81babbd..b52d0cbe9 100644 --- a/fsw/cfe-core/src/inc/cfe_es.h +++ b/fsw/cfe-core/src/inc/cfe_es.h @@ -979,22 +979,21 @@ uint32 CFE_ES_CalculateCRC(const void *DataPtr, uint32 DataLength, uint32 InputC /*****************************************************************************/ /** ** \ingroup CFEAPIESMisc -** \brief Process an exception detected by the underlying OS/PSP +** \brief Notification that an asynchronous event was detected by the underlying OS/PSP ** ** \par Description -** This hook routine is called from the PSP when an exception occurs +** This hook routine is called from the PSP when an exception or +** other asynchronous system event occurs ** ** \par Assumptions, External Events, and Notes: -** None. +** The PSP must guarantee that this function is only invoked from a +** context which may use OSAL primitives. In general this means that +** it shouldn't be _directly_ invoked from an ISR/signal context. ** -** \param[in] HostTaskId The OS (not OSAL) task ID -** \param[in] ReasonString Identifier from PSP -** \param[in] ContextPointer Context data from PSP -** \param[in] ContextSize Size of context data from PSP ** ******************************************************************************/ -void CFE_ES_ProcessCoreException(uint32 HostTaskId, const char *ReasonString, - const uint32 *ContextPointer, uint32 ContextSize); +void CFE_ES_ProcessAsyncEvent(void); + /**@}*/ /** @defgroup CFEAPIESCritData cFE Critical Data Store APIs diff --git a/fsw/cfe-core/src/inc/cfe_es_events.h b/fsw/cfe-core/src/inc/cfe_es_events.h index 78464a871..03da2eb37 100644 --- a/fsw/cfe-core/src/inc/cfe_es_events.h +++ b/fsw/cfe-core/src/inc/cfe_es_events.h @@ -1214,21 +1214,6 @@ **/ #define CFE_ES_FILEWRITE_ERR_EID 74 -/** \brief 'Error accessing ER Log,\%s not written.Stat=0x\%08x' -** \event 'Error accessing ER Log,\%s not written.Stat=0x\%08x' -** -** \par Type: ERROR -** -** \par Cause: -** -** This event message is generated in response to an Exception Reset Log Dump command and there is -** an error obtaining the contents of the ER Log. -** -** The \c 's' field identifies the filename of the file to which the data failed to write, -** the \c Stat field specifies, in hex, the error status returned from #CFE_PSP_GetResetArea. -**/ -#define CFE_ES_RST_ACCESS_EID 75 - /** \brief 'Error while deleting '\%s' from CDS, See SysLog.(Err=0x\%08X)' ** \event 'Error while deleting '\%s' from CDS, See SysLog.(Err=0x\%08X)' ** @@ -1518,6 +1503,19 @@ #define CFE_ES_BUILD_INF_EID 92 +/** \brief 'Error log write to file \%s already in progress' +** \event 'Error log write to file \%s already in progress' +** +** \par Type: ERROR +** +** \par Cause: +** +** This event message is generated when an Executive Services \link #CFE_ES_WRITE_ER_LOG_CC Dump Exception Reset Log +** Command \endlink is received before a previously-issued command has finished executing +** +**/ +#define CFE_ES_ERLOG_PENDING_ERR_EID 93 + #endif /* _cfe_es_events_ */ diff --git a/fsw/cfe-core/src/inc/cfe_evs_msg.h b/fsw/cfe-core/src/inc/cfe_evs_msg.h index 477b6caa8..a6fe29872 100644 --- a/fsw/cfe-core/src/inc/cfe_evs_msg.h +++ b/fsw/cfe-core/src/inc/cfe_evs_msg.h @@ -37,6 +37,7 @@ /********************************** Include Files ************************************/ #include "common_types.h" /* Basic data types */ +#include "cfe_evs_extern_typedefs.h" /* for EVS-specific types such as CFE_EVS_LogMode_Enum_t */ #include "cfe_time.h" /* Time library function definitions */ #include "cfe_sb.h" #include "cfe_es.h" diff --git a/fsw/cfe-core/src/inc/private/cfe_es_erlog_typedef.h b/fsw/cfe-core/src/inc/private/cfe_es_erlog_typedef.h index d10f9c8ec..b93fba5d4 100644 --- a/fsw/cfe-core/src/inc/private/cfe_es_erlog_typedef.h +++ b/fsw/cfe-core/src/inc/private/cfe_es_erlog_typedef.h @@ -34,6 +34,8 @@ #include #include /* Needed for CFE_TIME_SysTime_t */ +#define CFE_ES_ERLOG_DESCRIPTION_MAX_LENGTH 80 + /* ** Debug variables type */ @@ -47,7 +49,9 @@ typedef struct } CFE_ES_DebugVariables_t; /* -** Exception and Reset Log Structure +** Exception and Reset Log Base Structure +** +** This is the common data structure that is stored in RAM and log files */ typedef struct { @@ -59,11 +63,42 @@ typedef struct uint32 MaxProcessorResetCount; /* The maximum number before a Power On */ CFE_ES_DebugVariables_t DebugVars; /* ES Debug variables */ CFE_TIME_SysTime_t TimeCode; /* Time code */ - char Description[80]; /* The ascii data for the event */ - uint32 ContextSize; /* Indicates the context data is valid */ - uint32 AppID; /* The application ID */ - uint32 Context[CFE_PLATFORM_ES_ER_LOG_MAX_CONTEXT_SIZE / sizeof(uint32)]; /* cpu context */ -} CFE_ES_ERLog_t; + char Description[CFE_ES_ERLOG_DESCRIPTION_MAX_LENGTH]; /* The ascii data for the event */ +} CFE_ES_ERLog_BaseInfo_t; + + +/* +** Exception and Reset Log File Structure +** +** This is the "export" data structure that gets written to a log file +** It is intended to be binary-compatible with the historical definition of this +** structure, to work with existing tools that may read log files. +** +** Note that "AppID" really belongs in the base info, but it is kept here +** for backward compatibility. +*/ +typedef struct +{ + CFE_ES_ERLog_BaseInfo_t BaseInfo; /* basic info about the event */ + uint32 ContextSize; /* Indicates the context data is valid */ + uint32 AppID; /* The application ID */ + uint8 Context[CFE_PLATFORM_ES_ER_LOG_MAX_CONTEXT_SIZE]; /* cpu context */ +} CFE_ES_ERLog_FileEntry_t; + + +/* +** Exception and Reset Log Metadata Structure +** This is stored in ES RAM, not _directly_ written to ER log files. +*/ +typedef struct +{ + CFE_ES_ERLog_BaseInfo_t BaseInfo; /**< Core Log Data */ + uint32 AppID; /* The application ID */ + uint32 PspContextId; /**< Reference to context information stored in PSP */ +} CFE_ES_ERLog_MetaData_t; + + + diff --git a/fsw/cfe-core/src/inc/private/cfe_es_resetdata_typedef.h b/fsw/cfe-core/src/inc/private/cfe_es_resetdata_typedef.h index 872dcf3bb..aec73b459 100644 --- a/fsw/cfe-core/src/inc/private/cfe_es_resetdata_typedef.h +++ b/fsw/cfe-core/src/inc/private/cfe_es_resetdata_typedef.h @@ -63,7 +63,7 @@ typedef struct /* ** Exception and Reset log declaration */ - CFE_ES_ERLog_t ERLog[CFE_PLATFORM_ES_ER_LOG_ENTRIES]; + CFE_ES_ERLog_MetaData_t ERLog[CFE_PLATFORM_ES_ER_LOG_ENTRIES]; uint32 ERLogIndex; uint32 ERLogEntries; uint32 LastAppId; diff --git a/fsw/cfe-core/unit-test/es_UT.c b/fsw/cfe-core/unit-test/es_UT.c index e0a7a7ab3..125415600 100644 --- a/fsw/cfe-core/unit-test/es_UT.c +++ b/fsw/cfe-core/unit-test/es_UT.c @@ -2186,8 +2186,6 @@ void TestApps(void) void TestERLog(void) { int Return; - uint32 Context = 4; - char Context2[1000]; #ifdef UT_VERBOSE UT_Text("Begin Test Exception and Reset Log\n"); @@ -2199,65 +2197,18 @@ void TestERLog(void) */ ES_ResetUnitTest(); CFE_ES_ResetDataPtr->ERLogIndex = CFE_PLATFORM_ES_ER_LOG_ENTRIES + 1; - CFE_ES_ResetDataPtr->ERLog[0].ContextSize = 0; Return = CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, 1, - NULL, - &Context, - sizeof(int)); + NULL); UT_Report(__FILE__, __LINE__, Return == CFE_SUCCESS && - !strcmp(CFE_ES_ResetDataPtr->ERLog[0].Description, + !strcmp(CFE_ES_ResetDataPtr->ERLog[0].BaseInfo.Description, "No Description String Given.") && - CFE_ES_ResetDataPtr->ERLogIndex == 1 && - CFE_ES_ResetDataPtr->ERLog[0].ContextSize == sizeof(int), + CFE_ES_ResetDataPtr->ERLogIndex == 1, "CFE_ES_WriteToERLog", "Log entries exceeded; no description; valid context size"); - /* Test initial rolling over log entry, - * null description, - * and non-null context with zero size - */ - ES_ResetUnitTest(); - CFE_ES_ResetDataPtr->ERLogIndex = 0; - CFE_ES_ResetDataPtr->ERLog[0].ContextSize = 0; - Return = CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, - CFE_PSP_RST_TYPE_POWERON, - 1, - NULL, - &Context, - 0); - UT_Report(__FILE__, __LINE__, - Return == CFE_SUCCESS && - CFE_ES_ResetDataPtr->ERLogIndex == 1 && - CFE_ES_ResetDataPtr->ERLog[0].ContextSize == 0, - "CFE_ES_WriteToERLog", - "Log entries exceeded; no description; invalid context size"); - - /* Test rolling over log entry at end, - * non-null description, - * and non-null context with large size - */ - ES_ResetUnitTest(); - CFE_ES_ResetDataPtr->ERLogIndex = CFE_PLATFORM_ES_ER_LOG_ENTRIES - 1; - CFE_ES_ResetDataPtr->ERLog[CFE_PLATFORM_ES_ER_LOG_ENTRIES - 1].ContextSize = 0; - Return = CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, - CFE_PSP_RST_TYPE_POWERON, - 1, - "LogDescription", - (uint32 *) &Context2, - 9999999); - UT_Report(__FILE__, __LINE__, - Return == CFE_SUCCESS && - !strcmp(CFE_ES_ResetDataPtr->ERLog[ - CFE_PLATFORM_ES_ER_LOG_ENTRIES - 1].Description, - "LogDescription") && - CFE_ES_ResetDataPtr->ERLogIndex == 0 && - CFE_ES_ResetDataPtr->ERLog[ - CFE_PLATFORM_ES_ER_LOG_ENTRIES - 1].ContextSize == 9999999, - "CFE_ES_WriteToERLog", - "Log entries at maximum; description; oversized context"); /* Test non-rolling over log entry, * null description, @@ -2265,17 +2216,13 @@ void TestERLog(void) */ ES_ResetUnitTest(); CFE_ES_ResetDataPtr->ERLogIndex = 0; - CFE_ES_ResetDataPtr->ERLog[0].ContextSize = 0; Return = CFE_ES_WriteToERLog(CFE_ES_LogEntryType_CORE, CFE_PSP_RST_TYPE_POWERON, 1, - NULL, - NULL, - 1); + NULL); UT_Report(__FILE__, __LINE__, Return == CFE_SUCCESS && - CFE_ES_ResetDataPtr->ERLogIndex == 1 && - CFE_ES_ResetDataPtr->ERLog[0].ContextSize == 0, + CFE_ES_ResetDataPtr->ERLogIndex == 1, "CFE_ES_WriteToERLog", "No log entry rollover; no description; no context"); } @@ -2460,6 +2407,7 @@ void TestTask(void) uint32 Id; uint32 TestObjId; uint32 ResetType; + uint32 UT_ContextBuffer; union { CFE_SB_Msg_t Msg; @@ -3264,64 +3212,157 @@ void TestTask(void) "Clear E&R log"); /* Test successful writing of the E&R log */ + /* In the current implementation, it does not directly write the file, + * this just sets a flag for the background task */ ES_ResetUnitTest(); memset(&CmdBuf, 0, sizeof(CmdBuf)); strncpy(CmdBuf.WriteERlogCmd.Payload.FileName, "filename", sizeof(CmdBuf.WriteERlogCmd.Payload.FileName)); + CFE_ES_TaskData.BackgroundERLogDumpState.IsPending = false; + UT_CallTaskPipe(CFE_ES_TaskPipe, &CmdBuf.Msg, sizeof(CFE_ES_WriteERLog_t), + UT_TPID_CFE_ES_CMD_WRITE_ER_LOG_CC); + UT_Report(__FILE__, __LINE__, + CFE_ES_TaskData.BackgroundERLogDumpState.IsPending, + "CFE_ES_WriteERLogCmd", + "Write E&R log command; pending"); + UT_Report(__FILE__, __LINE__, + !UT_EventIsInHistory(CFE_ES_ERLOG_PENDING_ERR_EID), + "CFE_ES_WriteERLogCmd", + "Write E&R log command; no events"); + + /* sending the same command a second time should fail with an event + * indicating a file write is already pending. */ UT_CallTaskPipe(CFE_ES_TaskPipe, &CmdBuf.Msg, sizeof(CFE_ES_WriteERLog_t), UT_TPID_CFE_ES_CMD_WRITE_ER_LOG_CC); UT_Report(__FILE__, __LINE__, - UT_EventIsInHistory(CFE_ES_ERLOG2_EID), + UT_EventIsInHistory(CFE_ES_ERLOG_PENDING_ERR_EID), + "CFE_ES_WriteERLogCmd", + "Write E&R log command; already pending event"); + + /* calling the background job when no write pending should immediately return false, no event */ + ES_ResetUnitTest(); + memset(&CFE_ES_TaskData.BackgroundERLogDumpState, 0, sizeof(CFE_ES_TaskData.BackgroundERLogDumpState)); + UT_Report(__FILE__, __LINE__, + !CFE_ES_RunERLogDump(0, &CFE_ES_TaskData.BackgroundERLogDumpState), + "CFE_ES_RunERLogDump", + "Write E&R log; not pending"); + UT_Report(__FILE__, __LINE__, + !UT_EventIsInHistory(CFE_ES_ERLOG2_EID), + "CFE_ES_WriteERLogCmd", + "Write E&R log command; no file written event"); + + /* nominal condition - still returns false, but generates event */ + ES_ResetUnitTest(); + UT_ContextBuffer = 42; + UT_SetDataBuffer(UT_KEY(CFE_PSP_Exception_CopyContext),&UT_ContextBuffer, sizeof(UT_ContextBuffer), false); + CFE_ES_TaskData.BackgroundERLogDumpState.IsPending = true; + CFE_ES_RunERLogDump(0, &CFE_ES_TaskData.BackgroundERLogDumpState); + UT_Report(__FILE__, __LINE__, + !CFE_ES_TaskData.BackgroundERLogDumpState.IsPending, + "CFE_ES_RunERLogDump", + "Write E&R log; nominal, clear flag"); + UT_Report(__FILE__, __LINE__, + UT_EventIsInHistory(CFE_ES_ERLOG2_EID), "CFE_ES_WriteERLogCmd", - "Write E&R log; success"); + "Write E&R log command; file written event"); /* Test writing the E&R log with an OS create failure */ ES_ResetUnitTest(); - memset(&CmdBuf, 0, sizeof(CmdBuf)); + CFE_ES_TaskData.BackgroundERLogDumpState.IsPending = true; UT_SetForceFail(UT_KEY(OS_creat), OS_ERROR); - strncpy((char *) CmdBuf.WriteERlogCmd.Payload.FileName, "", - sizeof(CmdBuf.WriteERlogCmd.Payload.FileName)); - UT_CallTaskPipe(CFE_ES_TaskPipe, &CmdBuf.Msg, sizeof(CFE_ES_WriteERLog_t), - UT_TPID_CFE_ES_CMD_WRITE_ER_LOG_CC); + CFE_ES_RunERLogDump(0, &CFE_ES_TaskData.BackgroundERLogDumpState); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_ERLOG2_ERR_EID), - "CFE_ES_WriteERLogCmd", + "CFE_ES_RunERLogDump", "Write E&R log; OS create"); /* Test writing the E&R log with an OS write failure */ ES_ResetUnitTest(); - memset(&CmdBuf, 0, sizeof(CmdBuf)); + CFE_ES_TaskData.BackgroundERLogDumpState.IsPending = true; UT_SetForceFail(UT_KEY(OS_write), OS_ERROR); - strncpy((char *) CmdBuf.WriteERlogCmd.Payload.FileName, "n", - sizeof(CmdBuf.WriteERlogCmd.Payload.FileName)); - UT_CallTaskPipe(CFE_ES_TaskPipe, &CmdBuf.Msg, sizeof(CFE_ES_WriteERLog_t), - UT_TPID_CFE_ES_CMD_WRITE_ER_LOG_CC); + CFE_ES_RunERLogDump(0, &CFE_ES_TaskData.BackgroundERLogDumpState); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_FILEWRITE_ERR_EID), - "CFE_ES_WriteERLogCmd", + "CFE_ES_RunERLogDump", "Write E&R log; OS write"); /* Test writing the E&R log with a write header failure */ ES_ResetUnitTest(); - memset(&CmdBuf, 0, sizeof(CmdBuf)); + CFE_ES_TaskData.BackgroundERLogDumpState.IsPending = true; UT_SetDeferredRetcode(UT_KEY(CFE_FS_WriteHeader), 1, OS_ERROR); - UT_CallTaskPipe(CFE_ES_TaskPipe, &CmdBuf.Msg, sizeof(CFE_ES_WriteERLog_t), - UT_TPID_CFE_ES_CMD_WRITE_ER_LOG_CC); + CFE_ES_RunERLogDump(0, &CFE_ES_TaskData.BackgroundERLogDumpState); UT_Report(__FILE__, __LINE__, UT_EventIsInHistory(CFE_ES_FILEWRITE_ERR_EID), "CFE_ES_WriteERLogCmd", "Write E&R log; write header"); - /* Test writing the E&R log with a reset area failure */ + /* Test scan for exceptions in the PSP, should invoke a Processor Reset */ ES_ResetUnitTest(); - memset(&CmdBuf, 0, sizeof(CmdBuf)); - UT_SetStatusBSPResetArea(OS_ERROR, 0, CFE_TIME_ToneSignalSelect_PRIMARY); - UT_CallTaskPipe(CFE_ES_TaskPipe, &CmdBuf.Msg, sizeof(CFE_ES_WriteERLog_t), - UT_TPID_CFE_ES_CMD_WRITE_ER_LOG_CC); + UT_SetForceFail(UT_KEY(CFE_PSP_Exception_GetCount), 1); + CFE_ES_RunExceptionScan(0, NULL); UT_Report(__FILE__, __LINE__, - UT_EventIsInHistory(CFE_ES_RST_ACCESS_EID), - "CFE_ES_WriteERLogCmd", - "Write E&R log; reset area"); + UT_GetStubCount(UT_KEY(CFE_PSP_Restart)) == 1, + "CFE_ES_RunExceptionScan", + "Scan for exceptions; processor restart"); + + ES_ResetUnitTest(); + CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount = 0; + CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount = 1; + UT_SetForceFail(UT_KEY(CFE_PSP_Exception_GetCount), 1); + CFE_ES_RunExceptionScan(0, NULL); + /* first time should do a processor restart (limit reached) */ + UT_Report(__FILE__, __LINE__, + UT_GetStubCount(UT_KEY(CFE_PSP_Restart)) == 1, + "CFE_ES_RunExceptionScan", + "Scan for exceptions; processor restart"); + /* next time should do a poweron restart (limit reached) */ + CFE_ES_RunExceptionScan(0, NULL); + UT_Report(__FILE__, __LINE__, + UT_GetStubCount(UT_KEY(CFE_PSP_Restart)) == 2, + "CFE_ES_RunExceptionScan", + "Scan for exceptions; poweron restart"); + + /* nominal for app restart - associate exception with a task ID */ + OS_TaskCreate(&UT_ContextBuffer, "UT", NULL, NULL, 0, 0, 0); + UT_SetDataBuffer(UT_KEY(CFE_PSP_Exception_GetSummary), &UT_ContextBuffer, sizeof(UT_ContextBuffer), false); + CFE_ES_Global.TaskTable[1].RecordUsed = true; + CFE_ES_Global.TaskTable[1].AppId = 0; + CFE_ES_Global.TaskTable[1].TaskId = UT_ContextBuffer; + CFE_ES_Global.AppTable[0].AppState = CFE_ES_AppState_RUNNING; + CFE_ES_Global.AppTable[0].ControlReq.AppControlRequest = CFE_ES_RunStatus_APP_RUN; + CFE_ES_Global.AppTable[0].ControlReq.AppTimerMsec = 0; + CFE_ES_Global.AppTable[0].Type = CFE_ES_AppType_EXTERNAL; + CFE_ES_Global.AppTable[0].StartParams.ExceptionAction = CFE_ES_ExceptionAction_RESTART_APP; + CFE_ES_RunExceptionScan(0, NULL); + /* should have changed AppControlRequest from RUN to SYS_RESTART, + * and the call to CFE_PSP_Restart should NOT increment */ + UT_Report(__FILE__, __LINE__, + CFE_ES_Global.AppTable[0].ControlReq.AppControlRequest == CFE_ES_RunStatus_SYS_RESTART, + "CFE_ES_RunExceptionScan", + "Scan for exceptions; app restart request pending"); + + UT_Report(__FILE__, __LINE__, + UT_GetStubCount(UT_KEY(CFE_PSP_Restart)) == 2, + "CFE_ES_RunExceptionScan", + "Scan for exceptions; no psp restart"); + + /* repeat, but for a CORE app, which cannot be restarted */ + UT_SetDataBuffer(UT_KEY(CFE_PSP_Exception_GetSummary), &UT_ContextBuffer, sizeof(UT_ContextBuffer), false); + CFE_ES_Global.AppTable[0].ControlReq.AppControlRequest = CFE_ES_RunStatus_APP_RUN; + CFE_ES_Global.AppTable[0].Type = CFE_ES_AppType_CORE; + CFE_ES_RunExceptionScan(0, NULL); + UT_Report(__FILE__, __LINE__, + UT_GetStubCount(UT_KEY(CFE_PSP_Restart)) == 3, + "CFE_ES_RunExceptionScan", + "Scan for exceptions; core app, psp restart"); + + /* check failure of getting summary data */ + UT_SetForceFail(UT_KEY(CFE_PSP_Exception_GetSummary), CFE_PSP_NO_EXCEPTION_DATA); + CFE_ES_RunExceptionScan(0, NULL); + UT_Report(__FILE__, __LINE__, + UT_GetStubCount(UT_KEY(CFE_PSP_Restart)) == 4, + "CFE_ES_RunExceptionScan", + "Scan for exceptions; fail to get context"); /* Test clearing the log with a bad size in the verify command * length call @@ -4338,13 +4379,12 @@ void TestPerf(void) void TestAPI(void) { - uint32 Id, Id2; - uint32 TestObjId, TestObjId2; + uint32 Id; + uint32 TestObjId; char AppName[32]; char CounterName[11]; char CDSName[CFE_MISSION_ES_CDS_MAX_NAME_LENGTH + 2]; int i; - uint32 ExceptionContext = 0; int32 Return; uint8 Data[12]; uint32 ResetType; @@ -5328,86 +5368,6 @@ void TestAPI(void) (CounterCount == 5), "CFE_ES_SetGenCount", "Check value for counter set"); - /* Test handling of logging and reset after a core exception using - * a non-running app - */ - ES_ResetUnitTest(); - OS_TaskCreate(&TestObjId, "UT", NULL, NULL, 0, 0, 0); - Id = ES_UT_OSALID_TO_ARRAYIDX(TestObjId); - OS_TaskCreate(&TestObjId2, "UT", NULL, NULL, 0, 0, 0); - Id2 = ES_UT_OSALID_TO_ARRAYIDX(TestObjId2); - strncpy((char *)CFE_ES_Global.AppTable[Id].StartParams.Name, "appName", - sizeof(CFE_ES_Global.AppTable[Id].StartParams.Name)); - CFE_ES_Global.TaskTable[Id].RecordUsed = true; - CFE_ES_Global.AppTable[Id].Type = CFE_ES_AppType_EXTERNAL; - CFE_ES_Global.AppTable[Id].AppState = CFE_ES_AppState_EARLY_INIT; - CFE_ES_Global.TaskTable[Id2].RecordUsed = true; - CFE_ES_Global.TaskTable[Id2].AppId = Id; - OS_TaskCreate(&CFE_ES_Global.TaskTable[Id2].TaskId, NULL, NULL, NULL, - 0, 0, 0); - CFE_ES_Global.AppTable[Id].StartParams.ExceptionAction = - CFE_ES_ExceptionAction_RESTART_APP; - CFE_ES_ProcessCoreException(TestObjId & 0xFFFF, - "Reason String", - &ExceptionContext, - sizeof(ExceptionContext)); - UT_Report(__FILE__, __LINE__, - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_CANNOT_RESTART_APP]) && - UT_GetStubCount(UT_KEY(OS_printf)) == 1, - "CFE_ES_ProcessCoreException", - "Cannot restart a non-running application"); - - /* Test handling of logging and reset after a core exception; processor - * reset with no app restart - */ - ES_ResetUnitTest(); - UT_SetDataBuffer(UT_KEY(CFE_PSP_Restart), &ResetType, sizeof(ResetType), false); - OS_TaskCreate(&TestObjId, "UT", NULL, NULL, 0, 0, 0); - Id = ES_UT_OSALID_TO_ARRAYIDX(TestObjId); - OS_TaskCreate(&TestObjId2, "UT", NULL, NULL, 0, 0, 0); - Id2 = ES_UT_OSALID_TO_ARRAYIDX(TestObjId2); -// memset(CFE_ES_Global.TaskTable, 0, sizeof(CFE_ES_Global.TaskTable)); -// memset(CFE_ES_Global.AppTable, 0, sizeof(CFE_ES_Global.AppTable)); - strncpy((char *)CFE_ES_Global.AppTable[Id].StartParams.Name, "appName", - sizeof(CFE_ES_Global.AppTable[Id].StartParams.Name)); - CFE_ES_Global.TaskTable[Id2].RecordUsed = true; - CFE_ES_Global.TaskTable[Id2].AppId = Id; - OS_TaskCreate(&CFE_ES_Global.TaskTable[Id2].TaskId, NULL, NULL, NULL, - 0, 0, 0); - CFE_ES_Global.AppTable[Id].AppState = CFE_ES_AppState_RUNNING; - CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount = 0; - CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount = 5; - CFE_ES_Global.AppTable[3].StartParams.ExceptionAction = - CFE_ES_ExceptionAction_RESTART_APP + 1; - CFE_ES_ProcessCoreException(TestObjId2 & 0xFFFF, - "Reason String", - &ExceptionContext, - sizeof(ExceptionContext)); - UT_Report(__FILE__, __LINE__, - ResetType == CFE_PSP_RST_TYPE_PROCESSOR && - UT_GetStubCount(UT_KEY(CFE_PSP_Restart)) == 1, - "CFE_ES_ProcessCoreException", - "Processor reset with no application restart"); - - /* Test handling of logging and reset after a core exception; power on - * reset with no app restart - */ - ES_ResetUnitTest(); - UT_SetDataBuffer(UT_KEY(CFE_PSP_Restart), &ResetType, sizeof(ResetType), false); - CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount = 100; - CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount = 5; - CFE_ES_Global.AppTable[3].StartParams.ExceptionAction = - CFE_ES_ExceptionAction_RESTART_APP + 1; - CFE_ES_ProcessCoreException(OS_MAX_TASKS - 1, - "Reason String", - &ExceptionContext, - sizeof(ExceptionContext)); - UT_Report(__FILE__, __LINE__, - ResetType == CFE_PSP_RST_TYPE_POWERON && - UT_GetStubCount(UT_KEY(CFE_PSP_Restart)) == 1, - "CFE_ES_ProcessCoreException", - "Power on reset with no application restart"); - /* Test waiting for apps to initialize before continuing; transition from * initializing to running */ @@ -5601,68 +5561,6 @@ void TestAPI(void) "CFE_ES_GetGenCounterIDByName", "Null name"); - /* Test handling of logging and reset after failure to get the task info - * from the OS - */ - ES_ResetUnitTest(); - UT_SetDeferredRetcode(UT_KEY(OS_TaskGetInfo), 1, OS_INVALID_POINTER); - CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount = 0; - CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount = 5; - CFE_ES_ProcessCoreException(0xFFFFFFFF, - "Reason String", - &ExceptionContext, - sizeof(ExceptionContext)); - UT_Report(__FILE__, __LINE__, - CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount == 1 && - CFE_ES_ResetDataPtr->ResetVars.ES_CausedReset == true, - "CFE_ES_ProcessCoreException", - "Failure to get task info from OS"); - - /* Test handling of logging and reset where the host ID doesn't match - * the OS task ID - */ - ES_ResetUnitTest(); - OS_TaskCreate(&TestObjId, "UT", NULL, NULL, 0, 0, 0); - Id = ES_UT_OSALID_TO_ARRAYIDX(TestObjId); - CFE_ES_Global.TaskTable[Id].RecordUsed = true; - CFE_ES_Global.TaskTable[Id].AppId = Id; - CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount = 0; - CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount = 5; - CFE_ES_Global.AppTable[Id].StartParams.ExceptionAction = - CFE_ES_ExceptionAction_RESTART_APP; - CFE_ES_ProcessCoreException(0, - "Reason String", - &ExceptionContext, - sizeof(ExceptionContext)); - UT_Report(__FILE__, __LINE__, - UT_GetStubCount(UT_KEY(OS_printf)) == 0, - "CFE_ES_ProcessCoreException", - "Host ID doesn't match OS task ID"); - - /* Test handling of logging and reset where CFE_ES_GetTaskInfo fails */ - ES_ResetUnitTest(); - OS_TaskCreate(&TestObjId, "UT", NULL, NULL, 0, 0, 0); - Id = ES_UT_OSALID_TO_ARRAYIDX(TestObjId); - OS_TaskCreate(&TestObjId2, "UT", NULL, NULL, 0, 0, 0); - Id2 = ES_UT_OSALID_TO_ARRAYIDX(TestObjId2); - CFE_ES_Global.TaskTable[Id].RecordUsed = true; - CFE_ES_Global.TaskTable[Id].AppId = Id; - CFE_ES_ResetDataPtr->ResetVars.ProcessorResetCount = 0; - CFE_ES_ResetDataPtr->ResetVars.MaxProcessorResetCount = 5; - CFE_ES_Global.TaskTable[Id].RecordUsed = true; - CFE_ES_Global.TaskTable[Id].AppId = Id2; - CFE_ES_Global.AppTable[Id2].AppState = CFE_ES_AppState_UNDEFINED; - CFE_ES_Global.AppTable[Id2].StartParams.ExceptionAction = - CFE_ES_ExceptionAction_RESTART_APP; - CFE_ES_ProcessCoreException(Id, - "Reason String", - &ExceptionContext, - sizeof(ExceptionContext)); - UT_Report(__FILE__, __LINE__, - UT_GetStubCount(UT_KEY(OS_printf)) == 1, - "CFE_ES_ProcessCoreException", - "CFE_ES_GetTaskInfo failure"); - /* Test unsuccessful CDS registering */ ES_ResetUnitTest(); OS_TaskCreate(&TestObjId, "UT", NULL, NULL, 0, 0, 0); From 87b87c8c1146fdc612d08dff745b9917b8ce1771 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Wed, 6 May 2020 07:50:08 -0400 Subject: [PATCH 10/21] Update #411, documentation updates Correct items flagged as warnings in documenation build, and remove now-unused definition in sample platform config --- cmake/sample_defs/cpu1_platform_cfg.h | 46 --------------------------- docs/src/main.dox | 2 +- 2 files changed, 1 insertion(+), 47 deletions(-) diff --git a/cmake/sample_defs/cpu1_platform_cfg.h b/cmake/sample_defs/cpu1_platform_cfg.h index 1a7f3f5bd..167eedd53 100644 --- a/cmake/sample_defs/cpu1_platform_cfg.h +++ b/cmake/sample_defs/cpu1_platform_cfg.h @@ -1205,52 +1205,6 @@ */ #define CFE_PLATFORM_ES_DEFAULT_STACK_SIZE 8192 -/** -** \cfeescfg Define cFE Core Exception Function -** -** \par Description: -** This parameter defines the function-to-call when a CPU or floating point exception -** occurs. The parameter is defaulted to call the ES API function #CFE_ES_ProcessCoreException -** which handles the logging and reset from a system or cFE core exception. -** -** Note: Exception interrupts are trapped at the Platform Support Package (PSP) -** layer. In order to initiate the cFE platform defined response to an exception, this -** platform defined callback function must be prototyped and called from the PSP -** exception hook API function #CFE_PSP_ExceptionHook. For example: -** -** -- cfe_psp.h -- -** -** .... Prototype for exception ISR function implemented in CFE .... -** -** typedef void (*System_ExceptionFunc_t)(uint32 HostTaskId, -** const char *ReasonString, -** const uint32 *ContextPointer, -** uint32 ContextSize); -** -** -- cfe_pspexception.c -- -** -** .... Setup function pointer to CFE exception ISR callback .... -** -** static const System_ExceptionFunc_t CFE_ExceptionCallback = CFE_PLATFORM_ES_EXCEPTION_FUNCTION; -** -** void CFE_PSP_ExceptionHook (int task_id, int vector, uint8 *pEsf ) -** { -** .... platform-specific logic .... -** -** .... Use function pointer to call cFE routine to finish processing the exception .... -** -** CFE_ExceptionCallback((uint32)task_id, -** CFE_PSP_ExceptionReasonString, -** (uint32 *)&CFE_PSP_ExceptionContext, -** sizeof(CFE_PSP_ExceptionContext_t)); -** -** } -** -** \par Limits -** Must be a valid function name. -*/ -#define CFE_PLATFORM_ES_EXCEPTION_FUNCTION CFE_ES_ProcessCoreException - /** ** \cfeescfg Define EVS Task Priority ** diff --git a/docs/src/main.dox b/docs/src/main.dox index d3d583d84..d2cdf1efc 100644 --- a/docs/src/main.dox +++ b/docs/src/main.dox @@ -472,7 +472,7 @@
  • #CFE_ES_CalculateCRC - \copybrief CFE_ES_CalculateCRC
  • #CFE_ES_WriteToSysLog - \copybrief CFE_ES_WriteToSysLog -
  • #CFE_ES_ProcessCoreException - \copybrief CFE_ES_ProcessCoreException +
  • #CFE_ES_ProcessAsyncEvent - \copybrief CFE_ES_ProcessAsyncEvent
From 7c17fd8c3912a48891cd3cfdc590543e0c65cf18 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Wed, 6 May 2020 10:19:27 -0400 Subject: [PATCH 11/21] Fix #676, reference to deprecated CFE_SPACECRAFT_ID Should be CFE_MISSION_SPACECRAFT_ID --- fsw/cfe-core/src/sb/cfe_sb_msg_id_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsw/cfe-core/src/sb/cfe_sb_msg_id_util.c b/fsw/cfe-core/src/sb/cfe_sb_msg_id_util.c index a4e6c25bd..59fdb72f1 100644 --- a/fsw/cfe-core/src/sb/cfe_sb_msg_id_util.c +++ b/fsw/cfe-core/src/sb/cfe_sb_msg_id_util.c @@ -181,7 +181,7 @@ void CFE_SB_SetMsgId(CFE_SB_MsgPtr_t MsgPtr, CCSDS_WR_SUBSYSTEM_ID(MsgPtr->SpacePacket.ApidQ, CFE_SB_RD_SUBSYS_ID_FROM_MSGID(MsgIdVal)); - CCSDS_WR_SYSTEM_ID(MsgPtr->SpacePacket.ApidQ, CFE_SPACECRAFT_ID); + CCSDS_WR_SYSTEM_ID(MsgPtr->SpacePacket.ApidQ, CFE_MISSION_SPACECRAFT_ID); #endif }/* end CFE_SB_SetMsgId */ From 4908b722b61a54b054ee6d3440ea4580d3854593 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Wed, 6 May 2020 10:42:53 -0400 Subject: [PATCH 12/21] Issue #666, Define aligned message headers The "CFE_SB_CmdHdr_t" and "CFE_SB_TlmHdr_t" types were not defined such that they would have compatible alignment with (and thereby allow safe casting to/from) a CFE_SB_Msg_t type. This changes the definition to be a union so that the types are aligned correctly. --- fsw/cfe-core/src/inc/cfe_sb.h | 10 ++++++++-- fsw/cfe-core/src/sb/cfe_sb_util.c | 30 +++++++++++++++--------------- fsw/cfe-core/unit-test/sb_UT.c | 2 +- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/fsw/cfe-core/src/inc/cfe_sb.h b/fsw/cfe-core/src/inc/cfe_sb.h index 522ac5725..0b515e83b 100644 --- a/fsw/cfe-core/src/inc/cfe_sb.h +++ b/fsw/cfe-core/src/inc/cfe_sb.h @@ -155,10 +155,16 @@ typedef union { }CFE_SB_Msg_t; /** \brief Generic Software Bus Command Header Type Definition */ -typedef CCSDS_CommandPacket_t CFE_SB_CmdHdr_t; +typedef union { + CCSDS_CommandPacket_t Cmd; + CFE_SB_Msg_t BaseMsg; /**< Base type (primary header) */ +} CFE_SB_CmdHdr_t; /** \brief Generic Software Bus Telemetry Header Type Definition */ -typedef CCSDS_TelemetryPacket_t CFE_SB_TlmHdr_t; +typedef union { + CCSDS_TelemetryPacket_t Tlm; + CFE_SB_Msg_t BaseMsg; /**< Base type (primary header) */ +} CFE_SB_TlmHdr_t; #define CFE_SB_CMD_HDR_SIZE (sizeof(CFE_SB_CmdHdr_t))/**< \brief Size of #CFE_SB_CmdHdr_t in bytes */ #define CFE_SB_TLM_HDR_SIZE (sizeof(CFE_SB_TlmHdr_t))/**< \brief Size of #CFE_SB_TlmHdr_t in bytes */ diff --git a/fsw/cfe-core/src/sb/cfe_sb_util.c b/fsw/cfe-core/src/sb/cfe_sb_util.c index ab49485d8..abef9d505 100644 --- a/fsw/cfe-core/src/sb/cfe_sb_util.c +++ b/fsw/cfe-core/src/sb/cfe_sb_util.c @@ -211,21 +211,21 @@ CFE_TIME_SysTime_t CFE_SB_GetMsgTime(CFE_SB_MsgPtr_t MsgPtr) #if (CFE_MISSION_SB_PACKET_TIME_FORMAT == CFE_MISSION_SB_TIME_32_16_SUBS) - memcpy(&LocalSecs32, &TlmHdrPtr->Sec.Time[0], 4); - memcpy(&LocalSubs16, &TlmHdrPtr->Sec.Time[4], 2); + memcpy(&LocalSecs32, &TlmHdrPtr->Tlm.Sec.Time[0], 4); + memcpy(&LocalSubs16, &TlmHdrPtr->Tlm.Sec.Time[4], 2); /* convert packet data into CFE_TIME_SysTime_t format */ LocalSubs32 = ((uint32) LocalSubs16) << 16; #elif (CFE_MISSION_SB_PACKET_TIME_FORMAT == CFE_MISSION_SB_TIME_32_32_SUBS) - memcpy(&LocalSecs32, &TlmHdrPtr->Sec.Time[0], 4); - memcpy(&LocalSubs32, &TlmHdrPtr->Sec.Time[4], 4); + memcpy(&LocalSecs32, &TlmHdrPtr->Tlm.Sec.Time[0], 4); + memcpy(&LocalSubs32, &TlmHdrPtr->Tlm.Sec.Time[4], 4); /* no conversion necessary -- packet format = CFE_TIME_SysTime_t format */ #elif (CFE_MISSION_SB_PACKET_TIME_FORMAT == CFE_MISSION_SB_TIME_32_32_M_20) - memcpy(&LocalSecs32, &TlmHdrPtr->Sec.Time[0], 4); - memcpy(&LocalSubs32, &TlmHdrPtr->Sec.Time[4], 4); + memcpy(&LocalSecs32, &TlmHdrPtr->Tlm.Sec.Time[0], 4); + memcpy(&LocalSubs32, &TlmHdrPtr->Tlm.Sec.Time[4], 4); /* convert packet data into CFE_TIME_SysTime_t format */ LocalSubs32 = CFE_TIME_Micro2SubSecs((LocalSubs32 >> 12)); @@ -267,23 +267,23 @@ int32 CFE_SB_SetMsgTime(CFE_SB_MsgPtr_t MsgPtr, CFE_TIME_SysTime_t NewTime) /* convert time from CFE_TIME_SysTime_t format to packet format */ LocalSubs16 = (uint16) (NewTime.Subseconds >> 16); - memcpy(&TlmHdrPtr->Sec.Time[0], &NewTime.Seconds, 4); - memcpy(&TlmHdrPtr->Sec.Time[4], &LocalSubs16, 2); + memcpy(&TlmHdrPtr->Tlm.Sec.Time[0], &NewTime.Seconds, 4); + memcpy(&TlmHdrPtr->Tlm.Sec.Time[4], &LocalSubs16, 2); Result = CFE_SUCCESS; #elif (CFE_MISSION_SB_PACKET_TIME_FORMAT == CFE_MISSION_SB_TIME_32_32_SUBS) /* no conversion necessary -- packet format = CFE_TIME_SysTime_t format */ - memcpy(&TlmHdrPtr->Sec.Time[0], &NewTime.Seconds, 4); - memcpy(&TlmHdrPtr->Sec.Time[4], &NewTime.Subseconds, 4); + memcpy(&TlmHdrPtr->Tlm.Sec.Time[0], &NewTime.Seconds, 4); + memcpy(&TlmHdrPtr->Tlm.Sec.Time[4], &NewTime.Subseconds, 4); Result = CFE_SUCCESS; #elif (CFE_MISSION_SB_PACKET_TIME_FORMAT == CFE_MISSION_SB_TIME_32_32_M_20) /* convert time from CFE_TIME_SysTime_t format to packet format */ LocalSubs32 = CFE_TIME_Sub2MicroSecs(NewTime.Subseconds) << 12; - memcpy(&TlmHdrPtr->Sec.Time[0], &NewTime.Seconds, 4); - memcpy(&TlmHdrPtr->Sec.Time[4], &LocalSubs32, 4); + memcpy(&TlmHdrPtr->Tlm.Sec.Time[0], &NewTime.Seconds, 4); + memcpy(&TlmHdrPtr->Tlm.Sec.Time[4], &LocalSubs32, 4); Result = CFE_SUCCESS; #endif @@ -319,7 +319,7 @@ uint16 CFE_SB_GetCmdCode(CFE_SB_MsgPtr_t MsgPtr) /* Cast the input pointer to a Cmd Msg pointer */ CmdHdrPtr = (CFE_SB_CmdHdr_t *)MsgPtr; - return CCSDS_RD_FC(CmdHdrPtr->Sec); + return CCSDS_RD_FC(CmdHdrPtr->Cmd.Sec); }/* end CFE_SB_GetCmdCode */ @@ -339,7 +339,7 @@ int32 CFE_SB_SetCmdCode(CFE_SB_MsgPtr_t MsgPtr, /* Cast the input pointer to a Cmd Msg pointer */ CmdHdrPtr = (CFE_SB_CmdHdr_t *)MsgPtr; - CCSDS_WR_FC(CmdHdrPtr->Sec,CmdCode); + CCSDS_WR_FC(CmdHdrPtr->Cmd.Sec,CmdCode); return CFE_SUCCESS; @@ -362,7 +362,7 @@ uint16 CFE_SB_GetChecksum(CFE_SB_MsgPtr_t MsgPtr) /* cast the input pointer to a Cmd Msg pointer */ CmdHdrPtr = (CFE_SB_CmdHdr_t *)MsgPtr; - return CCSDS_RD_CHECKSUM(CmdHdrPtr->Sec); + return CCSDS_RD_CHECKSUM(CmdHdrPtr->Cmd.Sec); }/* end CFE_SB_GetChecksum */ diff --git a/fsw/cfe-core/unit-test/sb_UT.c b/fsw/cfe-core/unit-test/sb_UT.c index b6d4a3917..bf0340701 100644 --- a/fsw/cfe-core/unit-test/sb_UT.c +++ b/fsw/cfe-core/unit-test/sb_UT.c @@ -156,7 +156,7 @@ void Test_SB_Macros(void) */ void Test_SB_CCSDSSecHdr_Macros(void) { - CFE_SB_CmdHdr_t NoParamPkt; + CCSDS_CommandPacket_t NoParamPkt; uint32 ExpRtn; uint32 ActRtn; From 5e71fe2f494b9730dfb777a4d99e25b9919ff452 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Wed, 6 May 2020 10:54:38 -0400 Subject: [PATCH 13/21] Issue #666, Change message definitions to ensure alignment Update the CFE_ES_ShellTlm_t, CFE_TIME_ToneSignalCmd_t, and CFE_TIME_FakeToneCmd_t to use the CFE_SB_TlmHdr_t/CFE_SB_CmdHdr_t types to define the buffer, rather than a uint8 array. This should not change the size, as it was already defined using sizeof() this structure, but it will make it aligned correctly which resolves the compiler warning. Note that all CMD/TLM should really be defined this way, but this only selectively changes the places that were actually generating a compiler warning about this. There is a risk that padding will be added, but this change should not change the padding or size of messages in 32-bit builds. --- fsw/cfe-core/src/inc/cfe_es_msg.h | 2 +- fsw/cfe-core/src/inc/cfe_time_msg.h | 4 ++-- fsw/cfe-core/src/time/cfe_time_utils.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fsw/cfe-core/src/inc/cfe_es_msg.h b/fsw/cfe-core/src/inc/cfe_es_msg.h index bbd67a208..ed8a8955a 100644 --- a/fsw/cfe-core/src/inc/cfe_es_msg.h +++ b/fsw/cfe-core/src/inc/cfe_es_msg.h @@ -1586,7 +1586,7 @@ typedef struct typedef struct { - uint8 TlmHeader[CFE_SB_TLM_HDR_SIZE]; /**< \brief cFE Software Bus Telemetry Message Header */ + CFE_SB_TlmHdr_t TlmHeader; /**< \brief cFE Software Bus Telemetry Message Header */ CFE_ES_ShellPacket_Payload_t Payload; }CFE_ES_ShellTlm_t; diff --git a/fsw/cfe-core/src/inc/cfe_time_msg.h b/fsw/cfe-core/src/inc/cfe_time_msg.h index a7324dc9b..d492f806b 100644 --- a/fsw/cfe-core/src/inc/cfe_time_msg.h +++ b/fsw/cfe-core/src/inc/cfe_time_msg.h @@ -878,7 +878,7 @@ typedef struct */ typedef struct { - uint8 CmdHeader[CFE_SB_CMD_HDR_SIZE]; + CFE_SB_CmdHdr_t CmdHeader; } CFE_TIME_ToneSignalCmd_t; @@ -888,7 +888,7 @@ typedef struct */ typedef struct { - uint8 CmdHeader[CFE_SB_CMD_HDR_SIZE]; + CFE_SB_CmdHdr_t CmdHeader; } CFE_TIME_FakeToneCmd_t; diff --git a/fsw/cfe-core/src/time/cfe_time_utils.h b/fsw/cfe-core/src/time/cfe_time_utils.h index 728f69a80..2f48a5d4b 100644 --- a/fsw/cfe-core/src/time/cfe_time_utils.h +++ b/fsw/cfe-core/src/time/cfe_time_utils.h @@ -277,7 +277,7 @@ typedef struct /* ** Local 1Hz wake-up command packet (not related to time at tone)... */ - CCSDS_CommandPacket_t Local1HzCmd; + CFE_SB_CmdHdr_t Local1HzCmd; /* ** Time at the tone command packets (sent by time servers)... @@ -294,7 +294,7 @@ typedef struct * "tone signal" message above. */ #if (CFE_MISSION_TIME_CFG_FAKE_TONE == true) - CCSDS_CommandPacket_t ToneSendCmd; + CFE_SB_CmdHdr_t ToneSendCmd; #endif /* From 2a0494e5b63b1f1286c752bb935eb0ec3b3ccdfa Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Wed, 6 May 2020 10:54:38 -0400 Subject: [PATCH 14/21] Issue #666, Change message definitions to ensure alignment Update the CFE_ES_ShellTlm_t, CFE_TIME_ToneSignalCmd_t, and CFE_TIME_FakeToneCmd_t to use the CFE_SB_TlmHdr_t/CFE_SB_CmdHdr_t types to define the buffer, rather than a uint8 array. This should not change the size, as it was already defined using sizeof() this structure, but it will make it aligned correctly which resolves the compiler warning. Note that all CMD/TLM should really be defined this way, but this only selectively changes the places that were actually generating a compiler warning about this. There is a risk that padding will be added, but this change should not change the padding or size of messages in 32-bit builds. --- fsw/cfe-core/src/inc/cfe_es_msg.h | 2 +- fsw/cfe-core/src/inc/cfe_time_msg.h | 4 ++-- fsw/cfe-core/src/time/cfe_time_utils.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fsw/cfe-core/src/inc/cfe_es_msg.h b/fsw/cfe-core/src/inc/cfe_es_msg.h index fe82d51b4..2d702ac00 100644 --- a/fsw/cfe-core/src/inc/cfe_es_msg.h +++ b/fsw/cfe-core/src/inc/cfe_es_msg.h @@ -1601,7 +1601,7 @@ typedef struct */ typedef struct { - uint8 TlmHeader[CFE_SB_TLM_HDR_SIZE]; /**< \brief cFE Software Bus Telemetry Message Header */ + CFE_SB_TlmHdr_t TlmHeader; /**< \brief cFE Software Bus Telemetry Message Header */ CFE_ES_ShellPacket_Payload_t Payload; }CFE_ES_ShellTlm_t; #endif /* CFE_OMIT_DEPRECATED_6_7 */ diff --git a/fsw/cfe-core/src/inc/cfe_time_msg.h b/fsw/cfe-core/src/inc/cfe_time_msg.h index a7324dc9b..d492f806b 100644 --- a/fsw/cfe-core/src/inc/cfe_time_msg.h +++ b/fsw/cfe-core/src/inc/cfe_time_msg.h @@ -878,7 +878,7 @@ typedef struct */ typedef struct { - uint8 CmdHeader[CFE_SB_CMD_HDR_SIZE]; + CFE_SB_CmdHdr_t CmdHeader; } CFE_TIME_ToneSignalCmd_t; @@ -888,7 +888,7 @@ typedef struct */ typedef struct { - uint8 CmdHeader[CFE_SB_CMD_HDR_SIZE]; + CFE_SB_CmdHdr_t CmdHeader; } CFE_TIME_FakeToneCmd_t; diff --git a/fsw/cfe-core/src/time/cfe_time_utils.h b/fsw/cfe-core/src/time/cfe_time_utils.h index 26a0d34d1..79fc6880c 100644 --- a/fsw/cfe-core/src/time/cfe_time_utils.h +++ b/fsw/cfe-core/src/time/cfe_time_utils.h @@ -277,7 +277,7 @@ typedef struct /* ** Local 1Hz wake-up command packet (not related to time at tone)... */ - CCSDS_CommandPacket_t Local1HzCmd; + CFE_SB_CmdHdr_t Local1HzCmd; /* ** Time at the tone command packets (sent by time servers)... @@ -294,7 +294,7 @@ typedef struct * "tone signal" message above. */ #if (CFE_MISSION_TIME_CFG_FAKE_TONE == true) - CCSDS_CommandPacket_t ToneSendCmd; + CFE_SB_CmdHdr_t ToneSendCmd; #endif /* From 9cb0b5d03bcfd8214964e4d78af88e565ed4307f Mon Sep 17 00:00:00 2001 From: Jacob Hageman Date: Tue, 28 Apr 2020 10:11:16 -0400 Subject: [PATCH 15/21] Fix #639, Remove ES_APP_DEBUG functionality Deletes now unused CFE_ES_CountObjectCallback and CFE_ES_ListResourcesDebug. --- fsw/cfe-core/src/es/cfe_es_apps.c | 68 ++----------------------------- fsw/cfe-core/src/es/cfe_es_apps.h | 5 --- fsw/cfe-core/unit-test/es_UT.c | 25 ------------ fsw/cfe-core/unit-test/es_UT.h | 2 +- 4 files changed, 4 insertions(+), 96 deletions(-) diff --git a/fsw/cfe-core/src/es/cfe_es_apps.c b/fsw/cfe-core/src/es/cfe_es_apps.c index 66fe5fe18..46a319a95 100644 --- a/fsw/cfe-core/src/es/cfe_es_apps.c +++ b/fsw/cfe-core/src/es/cfe_es_apps.c @@ -53,9 +53,6 @@ */ #define ES_START_BUFF_SIZE 128 -/* For extra debug code */ -#undef ES_APP_DEBUG - /* ** ** Global Variables @@ -1238,11 +1235,6 @@ int32 CFE_ES_CleanUpApp(uint32 AppId) uint32 MainTaskId; int32 ReturnCode = CFE_SUCCESS; - #ifdef ES_APP_DEBUG - OS_printf("------------- Starting App Cleanup: AppID = %d -----------\n",AppId); - CFE_ES_ListResourcesDebug(); - #endif - /* ** Call the Table Clean up function */ @@ -1332,12 +1324,6 @@ int32 CFE_ES_CleanUpApp(uint32 AppId) CFE_ES_Global.AppTable[AppId].AppState = CFE_ES_AppState_UNDEFINED; - #ifdef ES_APP_DEBUG - OS_TaskDelay(1000); - CFE_ES_ListResourcesDebug(); - printf("--------- Finished CFE_ES_CleanUpApp-------------\n"); - #endif - CFE_ES_UnlockSharedData(__func__,__LINE__); return(ReturnCode); @@ -1348,8 +1334,7 @@ int32 CFE_ES_CleanUpApp(uint32 AppId) /* * Simple state structure used when cleaning up objects associated with tasks * - * This is used locally between CFE_ES_CleanupTaskResources and the - * CFE_ES_CountObjectCallback helper function. + * This is used locally by CFE_ES_CleanupTaskResources */ typedef struct { @@ -1362,9 +1347,9 @@ typedef struct /* **--------------------------------------------------------------------------------------- -** Name: CFE_ES_CountObjectCallback +** Name: CFE_ES_CleanupObjectCallback ** -** Purpose: Helper function for CFE_ES_ListResourcesDebug to count all objects. +** Purpose: Helper function clean up all objects. ** ** NOTE: This is called while holding the ES global lock **--------------------------------------------------------------------------------------- @@ -1528,53 +1513,6 @@ int32 CFE_ES_CleanupTaskResources(uint32 TaskId) } -/* -**--------------------------------------------------------------------------------------- -** Name: CFE_ES_CountObjectCallback -** -** Purpose: Helper function for CFE_ES_ListResourcesDebug to count all objects. -**--------------------------------------------------------------------------------------- -*/ -void CFE_ES_CountObjectCallback(uint32 ObjectId, void *arg) -{ - uint32 *CountState; - uint32 idtype; - - CountState = (uint32 *)arg; - idtype = OS_IdentifyObject(ObjectId); - if (idtype < OS_OBJECT_TYPE_USER) - { - ++CountState[idtype]; - } -} - - -/* -**--------------------------------------------------------------------------------------- -** Name: CFE_ES_ListResourcesDebug -** -** Purpose: List the resources. -**--------------------------------------------------------------------------------------- -*/ -int32 CFE_ES_ListResourcesDebug(void) -{ - uint32 CountState[OS_OBJECT_TYPE_USER]; - - memset(CountState,0,sizeof(CountState)); - OS_ForEachObject (0, CFE_ES_CountObjectCallback, CountState); - - OS_printf("OS Resources in Use:\n"); - OS_printf("Number of Tasks: %d\n", (int) CountState[OS_OBJECT_TYPE_OS_TASK]); - OS_printf("Number of Queues: %d\n", (int) CountState[OS_OBJECT_TYPE_OS_QUEUE]); - OS_printf("Number of Counting Semaphores: %d\n",(int) CountState[OS_OBJECT_TYPE_OS_COUNTSEM]); - OS_printf("Number of Binary Semaphores: %d\n",(int) CountState[OS_OBJECT_TYPE_OS_BINSEM]); - OS_printf("Number of Mutexes: %d\n", (int) CountState[OS_OBJECT_TYPE_OS_MUTEX]); - OS_printf("Number of Open Files: %d\n",(int) CountState[OS_OBJECT_TYPE_OS_STREAM]); - - return CFE_SUCCESS; - -} - /* **--------------------------------------------------------------------------------------- ** Name: CFE_ES_GetAppInfoInternal diff --git a/fsw/cfe-core/src/es/cfe_es_apps.h b/fsw/cfe-core/src/es/cfe_es_apps.h index 19ec02890..1f604bc93 100644 --- a/fsw/cfe-core/src/es/cfe_es_apps.h +++ b/fsw/cfe-core/src/es/cfe_es_apps.h @@ -223,11 +223,6 @@ int32 CFE_ES_CleanUpApp(uint32 AppId); */ int32 CFE_ES_CleanupTaskResources(uint32 TaskId); -/* -** Debug function to print out resource utilization -*/ -int32 CFE_ES_ListResourcesDebug(void); - /* ** Populate the cFE_ES_AppInfo structure with the data for an app ** This is an internal function for use in ES. diff --git a/fsw/cfe-core/unit-test/es_UT.c b/fsw/cfe-core/unit-test/es_UT.c index 071727a7f..d04feaac0 100644 --- a/fsw/cfe-core/unit-test/es_UT.c +++ b/fsw/cfe-core/unit-test/es_UT.c @@ -1687,16 +1687,6 @@ void TestApps(void) /* Test listing the OS resources in use */ ES_ResetUnitTest(); - /* Fail the first time, then succeed on the second in order to test - * both paths - */ - UT_SetDeferredRetcode(UT_KEY(OS_TaskGetInfo), 2, OS_ERROR); - UT_Report(__FILE__, __LINE__, - CFE_ES_ListResourcesDebug() == CFE_SUCCESS && - UT_GetStubCount(UT_KEY(OS_printf)) == 7, - "CFE_ES_ListResourcesDebug", - "Get task info failed"); - /* Test populating the application information structure with data */ ES_ResetUnitTest(); OS_TaskCreate(&TestObjId, "UT", NULL, NULL, 0, 0, 0); @@ -2092,21 +2082,6 @@ void TestApps(void) CFE_ES_CleanupTaskResources(TestObjId) == CFE_SUCCESS, "CFE_ES_CleanupTaskResources", "Get OS information failures"); - - /* Test cleaning up the OS resources for a task with failure to - * obtain information on mutex, binary, and counter semaphores, and - * queues, timers, and file descriptors - */ - ES_ResetUnitTest(); - UT_SetDeferredRetcode(UT_KEY(OS_MutSemGetInfo), 1, OS_ERROR); - UT_SetDeferredRetcode(UT_KEY(OS_BinSemGetInfo), 1, OS_ERROR); - UT_SetDeferredRetcode(UT_KEY(OS_CountSemGetInfo), 1, OS_ERROR); - UT_SetDeferredRetcode(UT_KEY(OS_QueueGetInfo), 1, OS_ERROR); - UT_SetDeferredRetcode(UT_KEY(OS_FDGetInfo), 1, OS_ERROR); - UT_Report(__FILE__, __LINE__, - CFE_ES_ListResourcesDebug() == CFE_SUCCESS, - "CFE_ES_ListResourcesDebug", - "Get OS information failures"); } void TestERLog(void) diff --git a/fsw/cfe-core/unit-test/es_UT.h b/fsw/cfe-core/unit-test/es_UT.h index 49d7816d4..982bb24af 100644 --- a/fsw/cfe-core/unit-test/es_UT.h +++ b/fsw/cfe-core/unit-test/es_UT.h @@ -137,7 +137,7 @@ void TestStartupErrorPaths(void); ** \sa #UT_Report, #UT_SetOSFail, #CFE_ES_ParseFileEntry ** \sa #UT_SetBSPloadAppFileResult, #CFE_ES_AppCreate, #UT_SetDummyFuncRtn ** \sa #CFE_ES_LoadLibrary, #CFE_ES_ScanAppTable, #CFE_ES_ProcessControlRequest -** \sa #CFE_ES_ListResourcesDebug, #CFE_ES_GetAppInfo, #CFE_ES_CleanUpApp +** \sa #CFE_ES_GetAppInfo, #CFE_ES_CleanUpApp ** \sa #CFE_ES_CleanupTaskResources ** ******************************************************************************/ From 56e024c79f57643f5c65a60ba59b52438069be03 Mon Sep 17 00:00:00 2001 From: Jacob Hageman Date: Fri, 24 Apr 2020 13:52:29 -0400 Subject: [PATCH 16/21] Fix #399, Deprecate decompress Removes untraced capabilities to decompress libraries or apps on load. For non-startup apps, FS can be used. For startup, recommendation is to compress/decompress as part of boot/startup vs individual applications/libs at load. Also fixes #291, by deprecating decompress it can be moved to the FS app. Also makes #135 N/A, static code analysis issues in decompress --- fsw/cfe-core/src/es/cfe_es_apps.c | 166 +--------- fsw/cfe-core/src/fs/cfe_fs_api.c | 3 +- fsw/cfe-core/src/fs/cfe_fs_decompress.c | 4 +- fsw/cfe-core/src/inc/cfe_error.h | 39 ++- fsw/cfe-core/src/inc/cfe_fs.h | 13 +- fsw/cfe-core/unit-test/es_UT.c | 172 +---------- fsw/cfe-core/unit-test/fs_UT.c | 156 ---------- fsw/cfe-core/unit-test/fs_UT.h | 1 - fsw/cfe-core/unit-test/ut_fs_zipfile.h | 385 ------------------------ fsw/cfe-core/ut-stubs/ut_fs_stubs.c | 3 + 10 files changed, 64 insertions(+), 878 deletions(-) delete mode 100644 fsw/cfe-core/unit-test/ut_fs_zipfile.h diff --git a/fsw/cfe-core/src/es/cfe_es_apps.c b/fsw/cfe-core/src/es/cfe_es_apps.c index 66fe5fe18..1efbc2e79 100644 --- a/fsw/cfe-core/src/es/cfe_es_apps.c +++ b/fsw/cfe-core/src/es/cfe_es_apps.c @@ -370,11 +370,6 @@ int32 CFE_ES_AppCreate(uint32 *ApplicationIdPtr, bool AppSlotFound; uint32 TaskId; uint32 ModuleId; - char FileNameOnly[OS_MAX_PATH_LEN]; - char RamDiskPath[OS_MAX_PATH_LEN]; - size_t StringLength; - bool IsRamDiskFile = false; - /* * The FileName must not be NULL @@ -408,96 +403,10 @@ int32 CFE_ES_AppCreate(uint32 *ApplicationIdPtr, if ( AppSlotFound == true) { /* - ** Check to see if the code is a Gzip file + ** Load the module */ - if ( CFE_FS_IsGzFile(FileName) == true ) - { - /* - ** Build up the destination path in the RAM disk - */ - (void) CFE_SB_MessageStringGet(RamDiskPath, - CFE_PLATFORM_ES_RAM_DISK_MOUNT_STRING"/", - NULL, - sizeof(RamDiskPath), - sizeof(CFE_PLATFORM_ES_RAM_DISK_MOUNT_STRING"/")); - - /* - ** Extract the filename from the path - */ - ReturnCode = CFE_FS_ExtractFilenameFromPath(FileName, FileNameOnly); - - if ( ReturnCode == CFE_SUCCESS ) - { - if ((strlen(RamDiskPath) + strlen(FileNameOnly)) < OS_MAX_PATH_LEN) - { - - /* - ** Cat the Filename to the RamDiskPath - */ - strcat(RamDiskPath, FileNameOnly); - - /* - ** Remove the ".gz" prefix from the filename - ** Already Determined that the filename ends in ".gz" - */ - StringLength = strlen(RamDiskPath); - RamDiskPath[StringLength - 3] = '\0'; - - /* - ** Decompress the file: - */ - ReturnCode = CFE_FS_Decompress( FileName, RamDiskPath); - - if ( ReturnCode != OS_SUCCESS ) - { - CFE_ES_WriteToSysLog("ES Startup: Unable to decompress Application File: %s\n",FileName); - - CFE_ES_LockSharedData(__func__,__LINE__); - CFE_ES_Global.AppTable[i].AppState = CFE_ES_AppState_UNDEFINED; /* Release slot */ - CFE_ES_UnlockSharedData(__func__,__LINE__); - - return(CFE_ES_ERR_APP_CREATE); - } - else - { - /* - ** All ready to use unzipped RAM disk file - */ - IsRamDiskFile = true; - ReturnCode = OS_ModuleLoad( &ModuleId, AppName, RamDiskPath); - } - } - else - { - /* Can't include the name string since it could be too long for the message */ - CFE_ES_WriteToSysLog("ES Startup: Application path plus file name length (%d) exceeds max allowed (%d)\n", - (int)(strlen(RamDiskPath) + strlen(FileNameOnly)), OS_MAX_PATH_LEN); - - CFE_ES_LockSharedData(__func__,__LINE__); - CFE_ES_Global.AppTable[i].AppState = CFE_ES_AppState_UNDEFINED; /* Release slot */ - CFE_ES_UnlockSharedData(__func__,__LINE__); - - return(CFE_ES_ERR_APP_CREATE); - } - - } - else - { - CFE_ES_WriteToSysLog("ES Startup: Unable to extract filename from path: %s.\n",FileName); - CFE_ES_LockSharedData(__func__,__LINE__); - CFE_ES_Global.AppTable[i].AppState = CFE_ES_AppState_UNDEFINED; /* Release slot */ - CFE_ES_UnlockSharedData(__func__,__LINE__); - return(CFE_ES_ERR_APP_CREATE); - } + ReturnCode = OS_ModuleLoad ( &ModuleId, AppName, FileName ); - } - else - { - /* - ** Load the module directly - */ - ReturnCode = OS_ModuleLoad ( &ModuleId, AppName, FileName ); - } /* ** If the Load was OK, then lookup the address of the entry point */ @@ -630,20 +539,6 @@ int32 CFE_ES_AppCreate(uint32 *ApplicationIdPtr, CFE_ES_UnlockSharedData(__func__,__LINE__); - /* - ** Remove the temporary RAM disk file - */ - if ( IsRamDiskFile == true ) - { - ReturnCode = OS_remove(RamDiskPath); - - if (ReturnCode != OS_SUCCESS) - { - CFE_ES_WriteToSysLog("ES Startup: Error removing temp RAM disk file, EC = 0x%08X\n", - (unsigned int) ReturnCode); - } - } - return(CFE_SUCCESS); } /* End If OS_TaskCreate */ @@ -670,14 +565,11 @@ int32 CFE_ES_LoadLibrary(uint32 *LibraryIdPtr, { CFE_ES_LibraryEntryFuncPtr_t FunctionPointer; CFE_ES_LibRecord_t * LibSlotPtr; - const char * ActualLoadFile; size_t StringLength; int32 Status; uint32 CheckSlot; uint32 ModuleId; bool IsModuleLoaded; - bool IsRamDiskFile; - char RamDiskPath[OS_MAX_PATH_LEN]; /* * First, should verify that the supplied "LibName" fits within the internal limit @@ -692,10 +584,7 @@ int32 CFE_ES_LoadLibrary(uint32 *LibraryIdPtr, /* ** Allocate an ES_LibTable entry */ - RamDiskPath[0] = 0; IsModuleLoaded = false; - IsRamDiskFile = false; - ActualLoadFile = NULL; LibSlotPtr = NULL; FunctionPointer = NULL; ModuleId = 0; @@ -771,42 +660,13 @@ int32 CFE_ES_LoadLibrary(uint32 *LibraryIdPtr, * ------------------- */ - /* - * STAGE 1: - * Figure out what filename to actually load, if a filename was given - * If the file is compressed, it must be uncompressed to a temp location first and that will be loaded - * - * (Note CFE_FS_IsGzFile() handles a NULL filename and properly returns false if NULL) - */ - if ( ! CFE_FS_IsGzFile(FileName) ) - { - /* - ** Not compressed - Load the library module directly - */ - ActualLoadFile = FileName; - } - else - { - /* - * Decompress to a temp file, and get that file name. - * Implemented in a helper function in the File Services subsystem which avoids clutter here. - */ - Status = CFE_FS_GetUncompressedFile(RamDiskPath, sizeof(RamDiskPath), - FileName, CFE_PLATFORM_ES_RAM_DISK_MOUNT_STRING); - if (Status == CFE_SUCCESS) - { - IsRamDiskFile = true; - ActualLoadFile = RamDiskPath; - } - } - /* * STAGE 2: * Do the OS_ModuleLoad() if is called for (i.e. ModuleLoadFile is NOT null) */ - if (Status == CFE_SUCCESS && ActualLoadFile != NULL) + if (Status == CFE_SUCCESS && FileName != NULL) { - Status = OS_ModuleLoad( &ModuleId, LibName, ActualLoadFile ); + Status = OS_ModuleLoad( &ModuleId, LibName, FileName ); if (Status == OS_SUCCESS) { Status = CFE_SUCCESS; /* just in case CFE_SUCCESS is different than OS_SUCCESS */ @@ -901,24 +761,6 @@ int32 CFE_ES_LoadLibrary(uint32 *LibraryIdPtr, OS_ModuleUnload( ModuleId ); } - /* - * If the above code had used a temp file, then remove it - */ - if ( IsRamDiskFile == true ) - { - /* - * Note: do not overwrite "Status" variable here; - * this contains a return code that needs to be - * sent back to the caller. - */ - - if (OS_remove(RamDiskPath) != OS_SUCCESS) - { - CFE_ES_WriteToSysLog("ES Startup: Error removing temp lib RAM disk file, EC = 0x%08X\n", - (unsigned int) Status); - } - } - /* Release Slot - No need to lock as it is resetting just a single bool value */ LibSlotPtr->RecordUsed = false; } diff --git a/fsw/cfe-core/src/fs/cfe_fs_api.c b/fsw/cfe-core/src/fs/cfe_fs_api.c index 56f792350..1f2a01357 100644 --- a/fsw/cfe-core/src/fs/cfe_fs_api.c +++ b/fsw/cfe-core/src/fs/cfe_fs_api.c @@ -326,7 +326,7 @@ int32 CFE_FS_ExtractFilenameFromPath(const char *OriginalPath, char *FileNameOnl return(ReturnCode); } - +#ifndef CFE_OMIT_DEPRECATED_6_7 /* ** Function: CFE_FS_IsGzFile - See API and header file for details */ @@ -439,6 +439,7 @@ int32 CFE_FS_GetUncompressedFile(char *OutputNameBuffer, uint32 OutputNameBuffer return Status; } +#endif /* CFE_OMIT_DEPRECATED_6_7 */ /************************/ /* End of File Comment */ diff --git a/fsw/cfe-core/src/fs/cfe_fs_decompress.c b/fsw/cfe-core/src/fs/cfe_fs_decompress.c index 1bb70306a..5e2a4d5ae 100644 --- a/fsw/cfe-core/src/fs/cfe_fs_decompress.c +++ b/fsw/cfe-core/src/fs/cfe_fs_decompress.c @@ -45,6 +45,8 @@ */ #include "cfe_fs_decompress.h" +#ifndef CFE_OMIT_DEPRECATED_6_7 /* Entire file will be removed in major release */ + /* ** Global data -- Note: The following Global Data should be removed. The CFE_FS_Decompress API is not ** re-entrant! In order to make sure that two apps will not corrupt the data @@ -1225,4 +1227,4 @@ uint32 FS_gz_updcrc( uint8 * s, uint32 n ) } - +#endif /* CFE_OMIT_DEPRECATED_6_7 */ diff --git a/fsw/cfe-core/src/inc/cfe_error.h b/fsw/cfe-core/src/inc/cfe_error.h index 0e93b4a34..763235f4b 100644 --- a/fsw/cfe-core/src/inc/cfe_error.h +++ b/fsw/cfe-core/src/inc/cfe_error.h @@ -674,15 +674,18 @@ */ #define CFE_FS_FNAME_TOO_LONG ((int32)0xc6000003) +#ifndef CFE_OMIT_DEPRECATED_6_7 /** - * @brief GZIP File Bad Data + * @brief DEPRECATED: GZIP File Bad Data + * @deprecated * * The GZIP file contains invalid data and cannot be read */ #define CFE_FS_GZIP_BAD_DATA ((int32)0xc6000004) /** - * @brief GZIP File Bad Code Block + * @brief DEPRECATED: GZIP File Bad Code Block + * @deprecated * * The GZIP file codeblock is bad, which means the file is * most likely corrupted @@ -690,7 +693,8 @@ #define CFE_FS_GZIP_BAD_CODE_BLOCK ((int32)0xc6000005) /** - * @brief GZIP Memory Buffer Exhausted + * @brief DEPRECATED: GZIP Memory Buffer Exhausted + * @deprecated * * The memory buffer used by the decompression routine is * exhausted. @@ -698,7 +702,8 @@ #define CFE_FS_GZIP_NO_MEMORY ((int32)0xc6000006) /** - * @brief GZIP CRC Error + * @brief DEPRECATED: GZIP CRC Error + * @deprecated * * There is a CRC error in the GZIP file, which means the * file is most likely corrupted. @@ -706,7 +711,8 @@ #define CFE_FS_GZIP_CRC_ERROR ((int32)0xc6000007) /** - * @brief GZIP Length Error + * @brief DEPRECATED: GZIP Length Error + * @deprecated * * There is a length error in the GZIP internal data * structures, which means the file is most likely corrupted. @@ -714,7 +720,8 @@ #define CFE_FS_GZIP_LENGTH_ERROR ((int32)0xc6000008) /** - * @brief GZIP Write Error + * @brief DEPRECATED: GZIP Write Error + * @deprecated * * An error occurred trying to write the uncompressed * file. @@ -722,14 +729,16 @@ #define CFE_FS_GZIP_WRITE_ERROR ((int32)0xc6000009) /** - * @brief GZIP Read Error + * @brief DEPRECATED: GZIP Read Error + * @deprecated * * An error occurred trying to read the GZIP file */ #define CFE_FS_GZIP_READ_ERROR ((int32)0xc600000A) /** - * @brief GZIP Open Output Error + * @brief DEPRECATED: GZIP Open Output Error + * @deprecated * * An error occurred trying to open the DestinationFile * where the GZIP file will be uncompressed. The @@ -739,7 +748,8 @@ #define CFE_FS_GZIP_OPEN_OUTPUT ((int32)0xc600000B) /** - * @brief GZIP Open Input Error + * @brief DEPRECATED: GZIP Open Input Error + * @deprecated * * An error occurred trying to open the GZIP file * to be decompressed. The function must be able to open @@ -749,7 +759,8 @@ #define CFE_FS_GZIP_OPEN_INPUT ((int32)0xc600000C) /** - * @brief GZIP Read Header Error + * @brief DEPRECATED: GZIP Read Header Error + * @deprecated * * An error occured trying to read the GZIP file header, * which means the file is most likely corrupted or @@ -758,7 +769,8 @@ #define CFE_FS_GZIP_READ_ERROR_HEADER ((int32)0xc600000D) /** - * @brief GZIP Index Error + * @brief DEPRECATED: GZIP Index Error + * @deprecated * * An error occurred trying to read the GZIP index, * which means the file is most likely corrupted. @@ -766,12 +778,15 @@ #define CFE_FS_GZIP_INDEX_ERROR ((int32)0xc600000E) /** - * @brief GZIP Not Zip File + * @brief DEPRECATED: GZIP Not Zip File + * @deprecated * * The file to be decompressed is not a valid GZIP file */ #define CFE_FS_GZIP_NON_ZIP_FILE ((int32)0xc600000F) +#endif /* CFE_OMIT_DEPRECATED_6_7 */ + /** * @brief Not Implemented * diff --git a/fsw/cfe-core/src/inc/cfe_fs.h b/fsw/cfe-core/src/inc/cfe_fs.h index e7fcf2d6a..5179bd592 100644 --- a/fsw/cfe-core/src/inc/cfe_fs.h +++ b/fsw/cfe-core/src/inc/cfe_fs.h @@ -189,13 +189,16 @@ int32 CFE_FS_WriteHeader(int32 FileDes, CFE_FS_Header_t *Hdr); int32 CFE_FS_SetTimestamp(int32 FileDes, CFE_TIME_SysTime_t NewTimestamp); /**@}*/ +#ifndef CFE_OMIT_DEPRECATED_6_7 + /** @defgroup CFEAPIFSCompress cFE Compressed File Management APIs * @{ */ /*****************************************************************************/ /** -** \brief Determines if a file is a Gzip/compressed file. +** \brief DEPRECATED; Determines if a file is a Gzip/compressed file. +** \deprecated ** ** \par Description ** This API will check the filename and return true if the file is @@ -216,7 +219,8 @@ bool CFE_FS_IsGzFile(const char *FileName); /*****************************************************************************/ /** -** \brief Decompresses the source file to the destination file. +** \brief DEPRECATED; Decompresses the source file to the destination file. +** \deprecated ** ** \par Description ** This API will decompress the source file to the file specified by @@ -245,7 +249,8 @@ int32 CFE_FS_Decompress( const char * SourceFile, const char * DestinationFile ) /*****************************************************************************/ /** -** \brief Decompresses the source file to a temporary file created in the temp dir +** \brief DEPRECATED; Decompresses the source file to a temporary file created in the temp dir +** \deprecated ** ** \par Description ** This is a wrapper around the #CFE_FS_Decompress function that @@ -270,6 +275,8 @@ int32 CFE_FS_GetUncompressedFile(char *OutputNameBuffer, uint32 OutputNameBuffer const char *GzipFileName, const char *TempDir); /**@}*/ +#endif /* CFE_OMIT_DEPRECATED_6_7 */ + /** @defgroup CFEAPIFSUtil cFE File Utility APIs * @{ */ diff --git a/fsw/cfe-core/unit-test/es_UT.c b/fsw/cfe-core/unit-test/es_UT.c index 071727a7f..4061db0b6 100644 --- a/fsw/cfe-core/unit-test/es_UT.c +++ b/fsw/cfe-core/unit-test/es_UT.c @@ -807,7 +807,6 @@ void TestApps(void) int Return; int j; CFE_ES_AppInfo_t AppInfo; - char LongFileName[OS_MAX_PATH_LEN + 9]; char LongLibraryName[sizeof(CFE_ES_Global.LibTable[0].LibName)+1]; uint32 Id, Id2, Id3, Id4; uint32 TestObjId, TestObjId2, TestObjId3, TestObjId4; @@ -967,61 +966,6 @@ void TestApps(void) "CFE_ES_AppCreate", "Application load/create; successful"); - /* Test application loading and creation with a file - * decompression failure - */ - UT_InitData(); - UT_SetDeferredRetcode(UT_KEY(CFE_FS_IsGzFile), 1, true); - UT_SetDeferredRetcode(UT_KEY(CFE_FS_Decompress), 1, -1); - Return = CFE_ES_AppCreate(&Id, - "ut/filename.gz", - "EntryPoint", - "AppName", - 170, - 8192, - 1); - UT_Report(__FILE__, __LINE__, - Return == CFE_ES_ERR_APP_CREATE && - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_DECOMPRESS_APP]), - "CFE_ES_AppCreate", - "Decompression failure"); - - /* Test application loading, creation and decompression */ - UT_InitData(); - UT_SetDeferredRetcode(UT_KEY(CFE_FS_IsGzFile), 1, true); - UT_SetDeferredRetcode(UT_KEY(CFE_FS_Decompress), 1, 0); - Return = CFE_ES_AppCreate(&Id, - "ut/filename.gz", - "EntryPoint", - "AppName", - 170, - 8192, - 1); - UT_Report(__FILE__, __LINE__, - Return == CFE_SUCCESS && - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_TABLE_SLOT_IN_USE]), - "CFE_ES_AppCreate", - "Decompression; successful"); - - /* Test application loading and creation where the file name cannot be - * extracted from the path - */ - UT_InitData(); - UT_SetDeferredRetcode(UT_KEY(CFE_FS_IsGzFile), 1, true); - UT_SetDeferredRetcode(UT_KEY(CFE_FS_ExtractFilenameFromPath), 1, -1); - Return = CFE_ES_AppCreate(&Id, - "ut/filename.gz", - "EntryPoint", - "AppName", - 170, - 8192, - 1); - UT_Report(__FILE__, __LINE__, - Return == CFE_ES_ERR_APP_CREATE && - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_EXTRACT_FILENAME_UT]), - "CFE_ES_AppCreate", - "File name extraction failure"); - /* Test application loading and creation where the file cannot be loaded */ UT_InitData(); UT_SetDeferredRetcode(UT_KEY(OS_ModuleLoad), 1, -1); @@ -1098,70 +1042,10 @@ void TestApps(void) "CFE_ES_AppCreate", "Module unload failure after entry point lookup failure"); - /* Test application loading and creation where the application file name - * is too long - */ - UT_InitData(); - strcpy(LongFileName, "ut57/"); - - for (j = 0; j < OS_MAX_PATH_LEN; j++) - { - strcat(LongFileName, "a"); - } - - strcat(LongFileName, ".gz"); - - UT_SetDeferredRetcode(UT_KEY(CFE_FS_IsGzFile), 1, true); - Return = CFE_ES_AppCreate(&Id, - LongFileName, - "EntryPoint", - "AppName", - 170, - 8192, - 1); - UT_Report(__FILE__, __LINE__, - Return == CFE_ES_ERR_APP_CREATE && - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_EXTRACT_FILENAME_UT57]), - "CFE_ES_AppCreate", - "Application file name too long"); - - /* Test application loading and creation where the application path + file - * name is too long - */ - UT_InitData(); - strcpy(LongFileName, "ut58/"); - - for (j = 0; j < OS_MAX_PATH_LEN - 6; j++) - { - strcat(LongFileName, "a"); - } - - strcat(LongFileName, ".gz"); - - UT_SetDeferredRetcode(UT_KEY(CFE_FS_IsGzFile), 1, true); - Return = CFE_ES_AppCreate(&Id, - LongFileName, - "EntryPoint", - "AppName", - 170, - 8192, - 1); - UT_Report(__FILE__, __LINE__, - Return == CFE_ES_ERR_APP_CREATE && - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_APP_PATH_FILE_TOO_LONG]), - "CFE_ES_AppCreate", - "Application file name + path too long"); - /* Test shared library loading and initialization where the initialization * routine returns an error */ - UT_InitData(); - - for (j = 0; j < CFE_PLATFORM_ES_MAX_LIBRARIES; j++) - { - CFE_ES_Global.LibTable[j].RecordUsed = false; - } - + ES_ResetUnitTest(); UT_SetDummyFuncRtn(-444); Return = CFE_ES_LoadLibrary(&Id, "filename", @@ -1186,15 +1070,12 @@ void TestApps(void) "CFE_ES_LoadLibrary", "Load shared library bad argument (library name too long)"); - /* Test successful shared library loading and initialization with a - * gzip'd library - */ + /* Test successful shared library loading and initialization */ UT_InitData(); - UT_SetDeferredRetcode(UT_KEY(CFE_FS_IsGzFile), 1, true); UT_SetDummyFuncRtn(OS_SUCCESS); Id = CFE_PLATFORM_ES_MAX_LIBRARIES; Return = CFE_ES_LoadLibrary(&Id, - "/cf/apps/tst_lib.bundle.gz", + "/cf/apps/tst_lib.bundle", "TST_LIB_Init", "TST_LIB"); UT_Report(__FILE__, __LINE__, @@ -1202,12 +1083,12 @@ void TestApps(void) Id < CFE_PLATFORM_ES_MAX_LIBRARIES && CFE_ES_Global.LibTable[Id].RecordUsed == true, "CFE_ES_LoadLibrary", - "Decompress library; successful"); + "successful"); /* Try loading same library again, should return the DUPLICATE code */ Id = CFE_PLATFORM_ES_MAX_LIBRARIES; Return = CFE_ES_LoadLibrary(&Id, - "/cf/apps/tst_lib.bundle.gz", + "/cf/apps/tst_lib.bundle", "TST_LIB_Init", "TST_LIB"); UT_Report(__FILE__, __LINE__, @@ -1215,66 +1096,44 @@ void TestApps(void) Id < CFE_PLATFORM_ES_MAX_LIBRARIES && CFE_ES_Global.LibTable[Id].RecordUsed == true, "CFE_ES_LoadLibrary", - "Unable to decompress library"); - - - /* Test shared library loading and initialization with a gzip'd library - * where the decompression fails. - * Only one test case is needed here now, since the CFE_FS_GetUncompressedFile - * is moved into FS and is individually tested in that module - */ - UT_InitData(); - memset(&CFE_ES_Global.LibTable, 0, sizeof(CFE_ES_Global.LibTable)); - UT_SetDeferredRetcode(UT_KEY(CFE_FS_IsGzFile), 1, true); - UT_SetForceFail(UT_KEY(CFE_FS_GetUncompressedFile), CFE_FS_BAD_ARGUMENT); - Return = CFE_ES_LoadLibrary(&Id, - "/cf/apps/tst_lib.bundle.gz", - "TST_LIB_Init", - "TST_LIB"); - UT_Report(__FILE__, __LINE__, - Return == CFE_FS_BAD_ARGUMENT, - "CFE_ES_LoadLibrary", - "Unable to decompress library"); + "Duplicate"); /* Test shared library loading and initialization where the library * fails to load */ - UT_InitData(); + ES_ResetUnitTest(); UT_SetDeferredRetcode(UT_KEY(OS_ModuleLoad), 1, -1); Return = CFE_ES_LoadLibrary(&Id, - "/cf/apps/tst_lib.bundle.gz", + "/cf/apps/tst_lib.bundle", "TST_LIB_Init", "TST_LIB"); UT_Report(__FILE__, __LINE__, - Return == CFE_ES_ERR_LOAD_LIB && - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_LOAD_SHARED_LIBRARY]), + Return == CFE_ES_ERR_LOAD_LIB, "CFE_ES_LoadLibrary", "Load shared library failure"); /* Test shared library loading and initialization where the library * entry point symbol cannot be found */ - UT_InitData(); + ES_ResetUnitTest(); UT_SetDeferredRetcode(UT_KEY(OS_SymbolLookup), 1, -1); Return = CFE_ES_LoadLibrary(&Id, - "/cf/apps/tst_lib.bundle.gz", + "/cf/apps/tst_lib.bundle", "TST_LIB_Init", "TST_LIB"); UT_Report(__FILE__, __LINE__, - Return == CFE_ES_ERR_LOAD_LIB && - UT_PrintfIsInHistory(UT_OSP_MESSAGES[UT_OSP_FIND_LIBRARY]), + Return == CFE_ES_ERR_LOAD_LIB, "CFE_ES_LoadLibrary", "Could not find library initialization symbol"); /* Test shared library loading and initialization where the library * initialization function fails and then must be cleaned up */ - UT_InitData(); - UT_SetDeferredRetcode(UT_KEY(CFE_FS_IsGzFile), 1, true); + ES_ResetUnitTest(); UT_SetForceFail(UT_KEY(OS_remove), OS_ERROR); /* for coverage of error path */ UT_SetForceFail(UT_KEY(dummy_function), -555); Return = CFE_ES_LoadLibrary(&Id, - "/cf/apps/tst_lib.bundle.gz", + "/cf/apps/tst_lib.bundle", "dummy_function", "TST_LIB"); UT_Report(__FILE__, __LINE__, @@ -1285,8 +1144,7 @@ void TestApps(void) /* Test shared library loading and initialization where there are no * library slots available */ - UT_InitData(); - + ES_ResetUnitTest(); for (j = 0; j < CFE_PLATFORM_ES_MAX_LIBRARIES; j++) { CFE_ES_Global.LibTable[j].RecordUsed = true; diff --git a/fsw/cfe-core/unit-test/fs_UT.c b/fsw/cfe-core/unit-test/fs_UT.c index 3993bed71..e95acd82f 100644 --- a/fsw/cfe-core/unit-test/fs_UT.c +++ b/fsw/cfe-core/unit-test/fs_UT.c @@ -39,7 +39,6 @@ ** Includes */ #include "fs_UT.h" -#include "cfe_fs_decompress.h" const char *FS_SYSLOG_MSGS[] = { @@ -48,9 +47,6 @@ const char *FS_SYSLOG_MSGS[] = "FS SharedData Mutex Give Err Stat=0x%x,App=%d,Function=%s\n" }; -static CFE_FS_Decompress_State_t UT_FS_Decompress_State; - - /* ** Functions */ @@ -70,8 +66,6 @@ void UtTest_Setup(void) UT_ADD_TEST(Test_CFE_FS_IsGzFile); UT_ADD_TEST(Test_CFE_FS_ExtractFileNameFromPath); UT_ADD_TEST(Test_CFE_FS_Private); - UT_ADD_TEST(Test_CFE_FS_Decompress); - UT_ADD_TEST(Test_CFE_FS_GetUncompressedFile); } /* @@ -433,153 +427,3 @@ void Test_CFE_FS_Private(void) #endif } -/* -** Tests for FS decompress functions (cfe_fs_decompress.c) -*/ -void Test_CFE_FS_Decompress(void) -{ - int NumBytes = 35400; - -#ifdef UT_VERBOSE - UT_Text("Begin Test Decompress\n"); -#endif - - /* Test file decompression with a file open failure */ - UT_InitData(); - UT_SetForceFail(UT_KEY(OS_open), OS_ERROR); - UT_Report(__FILE__, __LINE__, - CFE_FS_Decompress("Filename.gz", "Output") == - CFE_FS_GZIP_OPEN_INPUT, - "CFE_FS_Decompress", - "Open failed"); - - /* Test file decompression with a file create failure */ - UT_InitData(); - UT_SetForceFail(UT_KEY(OS_creat), OS_ERROR); - UT_Report(__FILE__, __LINE__, - CFE_FS_Decompress_Reentrant(&UT_FS_Decompress_State, - "Filename.gz", "Output") == - CFE_FS_GZIP_OPEN_OUTPUT, - "CFE_FS_Decompress", - "Create failed"); - - /* Test successful file decompression using local buffered data - * instead of real file I/O - */ - UT_InitData(); - UT_SetReadBuffer(fs_gz_test, NumBytes); - UT_Report(__FILE__, __LINE__, - CFE_FS_Decompress_Reentrant(&UT_FS_Decompress_State, - "fs_test.gz", "Output") == - CFE_SUCCESS, - "CFE_FS_Decompress", - "Decompress file - successful"); - - /* Test file decompression with a non-existent file */ - UT_InitData(); - UT_SetReadBuffer(&fs_gz_test[1], NumBytes - 1); - UT_Report(__FILE__, __LINE__, - CFE_FS_Decompress_Reentrant(&UT_FS_Decompress_State, - "fake", "Output") == - CFE_FS_GZIP_NON_ZIP_FILE, - "CFE_FS_Decompress", - "File does not exist"); - - /* Test successful decompression of an inflated type 1 (fixed Huffman - * codes) block - */ - UT_InitData(); - UT_Report(__FILE__, __LINE__, - FS_gz_inflate_fixed_Reentrant(&UT_FS_Decompress_State) == - CFE_SUCCESS, - "FS_gz_inflate_fixed", - "Inflated type 1 decompression - successful"); - - /* Test decompressing an inflated type 0 (stored) block */ - UT_InitData(); - UT_Report(__FILE__, __LINE__, - FS_gz_inflate_stored_Reentrant(&UT_FS_Decompress_State) != - CFE_SUCCESS, - "FS_gz_inflate_stored", - "Failed"); - - /* Test filling the input buffer with a FS error */ - UT_InitData(); - UT_SetDeferredRetcode(UT_KEY(OS_read), 1, 4); - UT_SetDeferredRetcode(UT_KEY(OS_read), 1, OS_ERROR); - UT_Report(__FILE__, __LINE__, - FS_gz_fill_inbuf_Reentrant(&UT_FS_Decompress_State) == EOF, - "FS_gz_fill_inbuf", - "gzip read error"); - - /* Test writing the output window and updating the CRC */ - UT_InitData(); - UT_SetDeferredRetcode(UT_KEY(OS_write), 1, -1); - UT_FS_Decompress_State.outcnt = 435; - FS_gz_flush_window_Reentrant(&UT_FS_Decompress_State); - UT_Report(__FILE__, __LINE__, - UT_FS_Decompress_State.outcnt == 0 && - UT_FS_Decompress_State.Error == CFE_FS_GZIP_WRITE_ERROR, - "FS_gz_flush_window", - "Write output - successful"); - -#ifdef UT_VERBOSE - UT_Text("End Test Decompress\n\n"); -#endif -} - -/* - * Test the CFE_FS_GetUncompressedFile() API which is a wrapper - * around CFE_FS_Decompress() that outputs to a temp file - */ -void Test_CFE_FS_GetUncompressedFile(void) -{ - int32 Status; - char OutputNameBuffer[OS_MAX_PATH_LEN + 32]; - - /* nominal run which must have valid gzip data */ - UT_InitData(); - UT_SetReadBuffer(fs_gz_test, 35400); - Status = CFE_FS_GetUncompressedFile(OutputNameBuffer, sizeof(OutputNameBuffer), - "/cf/Filename.gz", "/ramdisk"); - - UT_Report(__FILE__, __LINE__, - Status == CFE_SUCCESS, - "CFE_FS_GetUncompressedFile", - "Nominal Case"); - - UT_Report(__FILE__, __LINE__, - strcmp(OutputNameBuffer, "/ramdisk/Filename") == 0, - "CFE_FS_GetUncompressedFile", - "Output file name correct"); - - /* test case 2: CFE_FS_ExtractFilenameFromPath() fails */ - UT_InitData(); - Status = CFE_FS_GetUncompressedFile(OutputNameBuffer, sizeof(OutputNameBuffer), - NULL, "/Output"); - UT_Report(__FILE__, __LINE__, - Status == CFE_FS_BAD_ARGUMENT, - "CFE_FS_GetUncompressedFile", - "Bad Input Argument"); - - /* test case 3: Length too long */ - UT_InitData(); - Status = CFE_FS_GetUncompressedFile(OutputNameBuffer, 2, - "/cf/Filename.gz", "/ramdisk"); - UT_Report(__FILE__, __LINE__, - Status == CFE_FS_FNAME_TOO_LONG, - "CFE_FS_GetUncompressedFile", - "Name Too Long"); - - /* test case 4: CFE_FS_Decompress() fails */ - UT_InitData(); - UT_SetForceFail(UT_KEY(OS_open), OS_ERROR); - Status = CFE_FS_GetUncompressedFile(OutputNameBuffer, sizeof(OutputNameBuffer), - "/cf/Filename.gz", "/ramdisk"); - UT_Report(__FILE__, __LINE__, - Status == CFE_FS_GZIP_OPEN_INPUT, - "CFE_FS_GetUncompressedFile", - "Decompress failure"); - -} - diff --git a/fsw/cfe-core/unit-test/fs_UT.h b/fsw/cfe-core/unit-test/fs_UT.h index e279d18fe..0b522ce63 100644 --- a/fsw/cfe-core/unit-test/fs_UT.h +++ b/fsw/cfe-core/unit-test/fs_UT.h @@ -49,7 +49,6 @@ #include "cfe_fs_priv.h" #include "common_types.h" #include "ut_support.h" -#include "ut_fs_zipfile.h" /* FS unit test functions */ /*****************************************************************************/ diff --git a/fsw/cfe-core/unit-test/ut_fs_zipfile.h b/fsw/cfe-core/unit-test/ut_fs_zipfile.h deleted file mode 100644 index 4ff2e7ecc..000000000 --- a/fsw/cfe-core/unit-test/ut_fs_zipfile.h +++ /dev/null @@ -1,385 +0,0 @@ -/* -** GSC-18128-1, "Core Flight Executive Version 6.7" -** -** Copyright (c) 2006-2019 United States Government as represented by -** the Administrator of the National Aeronautics and Space Administration. -** All Rights Reserved. -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -/* This file represents the contents of a compressed (zipped) file for use by -** the FS unit tests -*/ - -#ifndef _ut_fs_zipfile_h_ -#define _ut_fs_zipfile_h_ - -static unsigned char fs_gz_test[] = { - 31, 139, 8, 8, 60, 114, 165, 72, 0, 3, 102, 115, 95, 85, 84, 0, 236, 91, 125, 116, 20, 85, 150, 175, 234, 143, 164, 3, 113, 186, 117, 178, 67, 84, 192, 0, 209, 73, 6, 23, 195, 138, 14, 136, 172, 129, 67, 205, 196, 25, 162, 81, 105, 97, 69, 37, 138, 104, 112, 249, 200, 144, 52, 31, 139, 145, 96, 119, 75, 202, 162, 103, 178, 35, 217, 201, 30, 153, 57, 8, 156, 49, 199, 101, 220, 172, 135, 13, 89, 7, 216, 6, 115, 210, 13, 228, 56, 97, 96, 48, - 42, 123, 108, 177, 117, 58, 118, 102, 204, 174, 172, 176, 248, 209, 123, 239, 123, 245, 170, 110, 117, 119, 2, 36, 243, 167, 125, 78, 167, 187, 234, 189, 123, 223, 239, 254, 238, 125, 247, 190, 247, 170, 243, 214, 197, 63, 125, 157, 43, 73, 146, 29, 222, 54, 120, 231, 195, 187, 215, 33, 73, 65, 248, 148, 225, 61, 19, 222, 75, 151, 86, 205, 253, 161, 242, 144, 114, 255, 189, 146, 249, 242, 72, 67, 190, 80, 46, 204, 228, 22, 42, 139, 23, 166, 203, 200, 70, 47, 28, 215, - 169, 143, 43, 177, 254, 245, 203, 55, 212, 155, 221, 51, 228, 11, 37, 105, 238, 7, 240, 233, 146, 36, 7, 29, 208, 33, 53, 154, 50, 203, 234, 234, 215, 174, 88, 253, 212, 16, 58, 230, 255, 159, 36, 237, 255, 14, 124, 246, 155, 227, 74, 146, 245, 59, 34, 220, 38, 163, 236, 252, 185, 11, 231, 82, 252, 112, 179, 220, 201, 123, 20, 73, 146, 224, 205, 105, 140, 245, 196, 99, 245, 143, 81, 252, 153, 242, 5, 5, 124, 4, 167, 148, 253, 5, 58, 54, 174, 124, 98, 104, - 29, 5, 197, 50, 154, 15, 122, 100, 11, 102, 171, 142, 85, 107, 158, 88, 186, 98, 245, 138, 250, 165, 79, 250, 86, 47, 203, 208, 49, 30, 116, 84, 227, 103, 154, 142, 60, 139, 142, 101, 107, 86, 173, 90, 179, 122, 40, 28, 141, 160, 99, 231, 87, 220, 11, 212, 22, 153, 124, 95, 186, 244, 241, 186, 58, 203, 181, 85, 71, 209, 228, 28, 169, 121, 162, 52, 172, 14, 51, 150, 238, 174, 172, 186, 247, 126, 211, 147, 85, 57, 60, 158, 138, 100, 246, 137, 190, 192, 183, 25, - 75, 181, 107, 86, 172, 174, 95, 190, 182, 78, 92, 103, 202, 239, 147, 185, 60, 229, 32, 199, 130, 247, 105, 223, 170, 218, 165, 245, 143, 61, 190, 114, 121, 54, 29, 225, 251, 114, 164, 143, 241, 115, 146, 108, 145, 195, 240, 92, 165, 219, 100, 206, 161, 5, 119, 223, 243, 99, 101, 254, 221, 66, 186, 26, 36, 154, 225, 179, 76, 150, 246, 60, 207, 177, 83, 187, 17, 83, 161, 196, 219, 255, 12, 138, 182, 111, 148, 37, 207, 28, 73, 26, 139, 208, 245, 62, 171, 28, 252, 125, - 31, 8, 30, 130, 62, 101, 210, 208, 175, 146, 245, 178, 244, 82, 150, 251, 223, 130, 247, 120, 137, 207, 251, 91, 124, 117, 107, 111, 89, 185, 226, 241, 91, 244, 16, 188, 94, 199, 112, 204, 241, 122, 249, 131, 127, 171, 116, 140, 89, 164, 205, 125, 117, 239, 249, 201, 78, 29, 3, 226, 29, 38, 13, 100, 190, 10, 179, 223, 198, 177, 103, 232, 205, 220, 23, 50, 123, 27, 120, 224, 253, 212, 178, 101, 75, 235, 166, 77, 159, 6, 208, 86, 60, 158, 69, 70, 150, 215, 100, 200, - 60, 176, 177, 174, 126, 249, 170, 105, 243, 12, 161, 111, 94, 223, 188, 190, 121, 89, 94, 79, 75, 234, 71, 254, 248, 160, 127, 192, 163, 61, 226, 80, 31, 46, 150, 66, 149, 46, 117, 65, 177, 195, 255, 166, 124, 248, 67, 155, 124, 28, 110, 185, 18, 56, 29, 207, 121, 213, 143, 22, 61, 248, 128, 127, 224, 102, 205, 151, 175, 61, 226, 209, 20, 151, 122, 155, 11, 42, 154, 58, 193, 1, 127, 119, 231, 195, 31, 237, 91, 193, 163, 234, 49, 223, 213, 255, 129, 85, 54, 121, - 245, 157, 183, 212, 219, 231, 37, 237, 243, 212, 19, 238, 14, 91, 32, 236, 251, 84, 237, 83, 175, 194, 34, 152, 180, 251, 195, 14, 205, 19, 252, 189, 239, 124, 104, 131, 227, 101, 204, 197, 154, 20, 12, 215, 219, 82, 189, 47, 187, 200, 69, 98, 202, 172, 28, 41, 164, 196, 212, 249, 197, 142, 136, 163, 184, 2, 180, 38, 118, 3, 150, 148, 55, 6, 151, 127, 117, 45, 92, 230, 64, 143, 196, 70, 214, 45, 174, 119, 219, 128, 221, 158, 129, 110, 154, 18, 7, 61, 46, 213, - 81, 156, 120, 127, 102, 142, 244, 178, 3, 84, 71, 152, 213, 8, 254, 153, 226, 124, 52, 78, 173, 47, 118, 96, 143, 47, 254, 83, 146, 240, 243, 45, 232, 9, 166, 250, 7, 74, 34, 243, 139, 89, 118, 131, 207, 124, 253, 211, 165, 127, 178, 186, 7, 67, 225, 71, 66, 130, 209, 143, 190, 9, 223, 106, 48, 27, 166, 110, 196, 18, 221, 156, 186, 177, 16, 62, 64, 17, 48, 54, 35, 129, 253, 150, 36, 166, 35, 76, 127, 135, 43, 71, 242, 75, 178, 191, 202, 1, 23, 55, - 197, 248, 168, 43, 238, 145, 244, 166, 80, 185, 203, 104, 237, 190, 29, 185, 224, 144, 67, 254, 99, 228, 42, 29, 11, 26, 4, 106, 174, 15, 129, 186, 35, 33, 255, 105, 214, 85, 245, 136, 111, 72, 232, 198, 165, 98, 0, 143, 62, 0, 10, 129, 124, 200, 127, 135, 142, 226, 161, 221, 38, 138, 162, 12, 140, 155, 1, 99, 68, 137, 67, 5, 234, 22, 157, 74, 244, 78, 253, 237, 178, 41, 89, 168, 223, 68, 108, 50, 195, 150, 143, 226, 111, 172, 224, 216, 118, 25, 216, 118, - 101, 193, 86, 102, 96, 203, 231, 216, 158, 214, 71, 63, 180, 203, 28, 161, 60, 3, 219, 135, 149, 12, 219, 24, 130, 173, 66, 96, 43, 32, 216, 102, 26, 146, 191, 231, 48, 142, 116, 214, 142, 3, 21, 64, 167, 160, 82, 45, 40, 78, 76, 252, 126, 142, 33, 82, 101, 136, 252, 90, 136, 96, 161, 73, 23, 73, 222, 110, 138, 44, 54, 68, 94, 167, 62, 43, 231, 97, 83, 206, 60, 151, 152, 120, 23, 231, 131, 139, 84, 235, 34, 170, 247, 156, 73, 12, 179, 251, 41, 19, - 125, 141, 161, 247, 52, 233, 177, 131, 244, 168, 205, 96, 230, 232, 2, 244, 192, 57, 85, 137, 139, 62, 27, 12, 138, 227, 254, 174, 25, 75, 142, 190, 201, 163, 212, 161, 71, 169, 198, 12, 241, 228, 192, 223, 198, 70, 184, 99, 104, 116, 205, 160, 209, 88, 96, 185, 186, 211, 114, 53, 195, 114, 85, 66, 174, 252, 93, 14, 62, 32, 75, 37, 207, 232, 67, 22, 178, 33, 143, 222, 202, 108, 130, 192, 120, 153, 127, 147, 102, 29, 169, 187, 137, 222, 255, 37, 251, 230, 238, 112, - 120, 154, 148, 151, 230, 137, 22, 213, 147, 156, 6, 109, 78, 4, 220, 100, 2, 78, 252, 20, 102, 45, 244, 19, 77, 205, 102, 147, 187, 67, 121, 169, 73, 57, 21, 242, 255, 230, 86, 17, 129, 245, 55, 68, 148, 29, 249, 44, 124, 120, 247, 86, 179, 123, 255, 172, 124, 233, 138, 241, 237, 202, 138, 111, 39, 193, 247, 231, 177, 136, 111, 151, 104, 106, 163, 248, 188, 187, 154, 188, 127, 24, 22, 95, 59, 193, 247, 207, 160, 41, 4, 246, 188, 24, 252, 47, 112, 186, 178, 93, - 245, 54, 71, 148, 109, 184, 44, 250, 82, 243, 109, 215, 26, 154, 181, 202, 109, 159, 253, 186, 19, 201, 174, 31, 227, 238, 248, 65, 202, 221, 113, 111, 170, 52, 10, 90, 239, 17, 234, 58, 137, 167, 81, 83, 19, 211, 212, 164, 122, 3, 17, 165, 81, 215, 212, 164, 53, 4, 180, 202, 198, 172, 154, 220, 193, 147, 99, 134, 36, 233, 102, 227, 190, 20, 170, 146, 77, 94, 196, 224, 81, 115, 240, 100, 161, 184, 25, 38, 84, 189, 201, 116, 15, 195, 70, 47, 97, 67, 27, 26, - 200, 144, 222, 218, 157, 213, 91, 125, 4, 66, 249, 24, 244, 214, 110, 209, 20, 179, 68, 211, 238, 38, 229, 244, 176, 248, 18, 4, 95, 50, 111, 72, 124, 165, 217, 241, 185, 59, 194, 170, 178, 135, 66, 156, 46, 20, 15, 18, 136, 191, 4, 197, 188, 171, 104, 189, 96, 182, 106, 222, 61, 170, 183, 111, 88, 144, 184, 236, 22, 32, 127, 48, 52, 200, 105, 67, 131, 60, 124, 248, 3, 151, 90, 217, 70, 145, 222, 46, 180, 187, 76, 237, 137, 207, 92, 28, 105, 247, 225, 143, - 93, 170, 175, 77, 116, 241, 200, 36, 8, 251, 180, 134, 182, 188, 153, 195, 2, 46, 36, 128, 91, 92, 35, 4, 236, 81, 43, 247, 102, 5, 92, 68, 0, 207, 51, 1, 123, 84, 223, 94, 209, 165, 36, 13, 240, 222, 75, 0, 46, 35, 128, 227, 185, 35, 4, 92, 168, 86, 182, 103, 5, 60, 147, 0, 254, 199, 92, 3, 112, 161, 234, 107, 23, 93, 202, 211, 0, 183, 95, 2, 112, 5, 1, 124, 235, 208, 128, 47, 53, 193, 23, 203, 89, 38, 120, 21, 129, 123, 54, 231, - 18, 19, 188, 154, 0, 121, 53, 103, 196, 64, 106, 179, 1, 169, 33, 64, 254, 238, 82, 64, 26, 9, 144, 73, 172, 51, 191, 191, 65, 166, 9, 225, 244, 137, 132, 63, 38, 7, 194, 238, 192, 114, 121, 68, 179, 125, 95, 214, 217, 222, 68, 144, 254, 171, 83, 159, 237, 251, 140, 10, 103, 182, 106, 202, 62, 85, 137, 13, 95, 224, 136, 33, 139, 157, 67, 130, 188, 107, 72, 144, 135, 99, 46, 85, 233, 156, 151, 73, 114, 27, 33, 121, 134, 81, 249, 8, 244, 115, 14, 6, - 157, 43, 48, 10, 26, 13, 205, 152, 230, 237, 204, 243, 12, 139, 191, 147, 224, 111, 101, 10, 149, 211, 135, 19, 54, 157, 118, 217, 54, 34, 218, 15, 100, 165, 61, 76, 176, 207, 116, 232, 180, 31, 48, 170, 23, 161, 189, 242, 128, 90, 25, 31, 190, 82, 17, 216, 31, 216, 71, 74, 123, 56, 11, 237, 177, 108, 180, 247, 17, 232, 13, 118, 147, 246, 176, 81, 153, 40, 237, 113, 205, 23, 206, 43, 163, 248, 221, 1, 92, 151, 164, 217, 48, 72, 108, 152, 96, 55, 231, 128, - 203, 70, 150, 139, 35, 154, 159, 23, 136, 13, 206, 68, 143, 237, 18, 147, 81, 50, 7, 236, 223, 142, 157, 149, 120, 202, 229, 111, 136, 167, 220, 193, 154, 84, 42, 197, 67, 194, 174, 135, 132, 27, 116, 119, 43, 239, 203, 70, 181, 33, 194, 253, 146, 105, 69, 249, 37, 173, 24, 114, 25, 209, 77, 195, 231, 250, 68, 190, 13, 215, 12, 102, 185, 178, 209, 20, 209, 221, 164, 188, 221, 216, 240, 118, 170, 126, 146, 81, 112, 232, 192, 195, 88, 93, 66, 128, 255, 10, 140, 2, - 45, 146, 111, 28, 152, 102, 152, 80, 70, 53, 233, 197, 193, 188, 213, 216, 240, 190, 228, 14, 94, 101, 16, 228, 208, 9, 250, 27, 157, 32, 11, 27, 181, 35, 103, 35, 98, 101, 227, 107, 9, 217, 136, 24, 165, 133, 178, 225, 141, 52, 121, 211, 216, 168, 186, 76, 54, 22, 19, 54, 112, 141, 159, 201, 70, 117, 38, 27, 53, 217, 216, 48, 82, 185, 217, 152, 156, 36, 198, 142, 224, 81, 169, 89, 5, 178, 129, 83, 149, 29, 70, 162, 182, 145, 84, 188, 195, 223, 245, 204, - 146, 71, 151, 138, 141, 150, 56, 14, 152, 92, 138, 187, 158, 127, 185, 137, 238, 149, 94, 185, 224, 196, 68, 78, 181, 243, 14, 154, 167, 19, 31, 114, 168, 135, 75, 79, 24, 183, 216, 246, 241, 21, 246, 93, 134, 111, 17, 113, 119, 65, 177, 75, 93, 200, 79, 53, 46, 174, 231, 155, 76, 174, 183, 213, 212, 11, 251, 76, 127, 195, 57, 169, 190, 78, 180, 237, 52, 219, 160, 33, 85, 255, 144, 104, 104, 75, 107, 152, 43, 26, 218, 179, 161, 132, 173, 38, 98, 225, 151, 56, - 175, 5, 214, 57, 169, 205, 144, 125, 158, 191, 153, 241, 44, 110, 6, 195, 62, 112, 103, 60, 197, 110, 114, 173, 157, 196, 157, 91, 113, 249, 10, 99, 250, 190, 23, 242, 239, 215, 121, 130, 117, 105, 119, 154, 72, 152, 248, 107, 81, 200, 127, 156, 176, 35, 6, 10, 57, 108, 120, 121, 220, 128, 117, 82, 87, 39, 115, 218, 111, 226, 81, 203, 51, 123, 92, 40, 142, 82, 47, 90, 54, 203, 197, 186, 15, 31, 253, 46, 250, 240, 195, 207, 177, 119, 47, 229, 227, 189, 98, 51, - 131, 42, 108, 9, 192, 59, 245, 101, 235, 196, 79, 58, 78, 178, 43, 244, 218, 233, 233, 18, 109, 85, 6, 141, 70, 229, 92, 114, 129, 80, 117, 129, 58, 102, 64, 218, 12, 161, 250, 89, 49, 183, 202, 197, 66, 149, 119, 139, 17, 35, 188, 3, 33, 101, 176, 20, 156, 52, 0, 108, 128, 167, 60, 66, 4, 252, 131, 50, 245, 139, 132, 84, 130, 72, 85, 158, 11, 249, 127, 87, 44, 252, 59, 136, 39, 31, 120, 68, 136, 167, 30, 206, 85, 60, 190, 184, 208, 32, 141, 175, - 1, 24, 101, 182, 50, 232, 14, 46, 96, 174, 250, 162, 216, 244, 138, 176, 76, 247, 10, 111, 66, 175, 188, 87, 76, 39, 3, 87, 138, 143, 216, 132, 153, 93, 197, 220, 3, 15, 62, 176, 101, 32, 236, 196, 179, 55, 230, 133, 190, 27, 209, 11, 143, 252, 47, 118, 119, 153, 221, 187, 149, 243, 80, 17, 2, 234, 145, 206, 249, 82, 230, 25, 207, 29, 32, 132, 39, 96, 193, 149, 23, 83, 41, 205, 155, 175, 182, 84, 195, 151, 228, 183, 133, 34, 143, 169, 72, 11, 177, 62, - 178, 182, 48, 24, 152, 167, 194, 31, 63, 19, 114, 164, 66, 40, 226, 63, 136, 127, 37, 95, 183, 166, 4, 102, 43, 249, 190, 169, 154, 50, 94, 63, 241, 9, 86, 97, 11, 51, 134, 43, 45, 52, 149, 246, 239, 206, 195, 147, 153, 241, 232, 213, 190, 72, 240, 9, 232, 137, 193, 152, 188, 67, 244, 45, 33, 0, 88, 179, 54, 63, 24, 128, 25, 51, 57, 197, 174, 68, 183, 34, 194, 207, 65, 108, 240, 172, 59, 200, 251, 171, 193, 26, 148, 82, 250, 84, 229, 140, 214, 130, - 119, 102, 121, 207, 212, 77, 214, 66, 172, 177, 178, 143, 183, 8, 61, 101, 166, 158, 72, 16, 45, 242, 88, 208, 148, 83, 52, 213, 20, 13, 35, 65, 116, 155, 73, 209, 112, 94, 14, 242, 254, 170, 210, 171, 49, 138, 1, 196, 58, 0, 81, 157, 13, 68, 5, 25, 197, 59, 30, 219, 108, 28, 46, 174, 246, 164, 147, 49, 152, 156, 201, 135, 69, 231, 197, 180, 115, 220, 228, 72, 61, 81, 122, 88, 141, 66, 87, 88, 9, 72, 27, 221, 220, 11, 224, 247, 238, 254, 50, 8, - 114, 157, 61, 37, 126, 162, 72, 40, 170, 74, 183, 109, 22, 235, 179, 246, 159, 152, 218, 234, 172, 106, 39, 155, 106, 133, 154, 106, 226, 220, 110, 216, 44, 113, 27, 117, 5, 16, 53, 144, 67, 48, 226, 231, 135, 2, 220, 221, 236, 224, 86, 247, 212, 51, 12, 83, 192, 31, 118, 240, 128, 12, 5, 55, 96, 104, 133, 97, 169, 22, 75, 206, 18, 35, 212, 16, 160, 45, 44, 38, 109, 50, 83, 160, 7, 164, 6, 11, 103, 238, 93, 23, 172, 161, 253, 82, 90, 132, 118, 26, - 241, 206, 61, 140, 0, 204, 128, 223, 144, 161, 252, 26, 149, 69, 13, 15, 43, 201, 221, 18, 214, 135, 9, 132, 235, 111, 227, 1, 165, 5, 90, 16, 167, 238, 205, 109, 193, 3, 240, 81, 174, 242, 155, 66, 111, 173, 169, 55, 21, 52, 25, 129, 169, 178, 54, 96, 226, 224, 177, 161, 114, 201, 16, 234, 81, 217, 172, 139, 40, 167, 48, 215, 99, 40, 28, 57, 255, 174, 218, 82, 207, 208, 223, 153, 226, 82, 145, 96, 173, 46, 31, 81, 88, 50, 232, 127, 219, 105, 206, 54, - 143, 131, 248, 181, 70, 184, 81, 137, 246, 191, 64, 58, 117, 154, 240, 66, 48, 22, 164, 187, 62, 57, 84, 207, 38, 78, 239, 212, 96, 61, 139, 220, 132, 166, 36, 102, 43, 103, 214, 141, 69, 24, 193, 133, 152, 39, 198, 107, 222, 132, 218, 178, 144, 216, 217, 72, 19, 198, 66, 22, 221, 9, 62, 172, 174, 134, 7, 168, 53, 156, 123, 52, 37, 90, 62, 91, 233, 113, 251, 95, 64, 18, 188, 81, 77, 233, 41, 237, 173, 192, 6, 38, 122, 56, 134, 41, 82, 9, 200, 189, - 108, 63, 199, 71, 106, 50, 71, 74, 42, 226, 102, 43, 181, 163, 7, 130, 155, 5, 0, 70, 132, 4, 250, 235, 166, 225, 55, 15, 180, 148, 122, 132, 68, 51, 117, 12, 195, 198, 254, 206, 86, 18, 107, 95, 77, 131, 153, 8, 249, 87, 76, 225, 73, 219, 174, 36, 202, 231, 36, 64, 116, 157, 62, 179, 156, 56, 179, 78, 59, 144, 81, 189, 143, 71, 237, 149, 195, 50, 188, 49, 187, 111, 156, 194, 23, 40, 106, 75, 45, 35, 75, 232, 97, 101, 141, 40, 101, 251, 1, 126, - 141, 165, 64, 168, 10, 249, 127, 50, 69, 44, 53, 215, 125, 55, 243, 190, 106, 152, 179, 211, 52, 167, 177, 225, 188, 84, 63, 69, 171, 132, 26, 52, 24, 170, 149, 67, 47, 50, 16, 215, 168, 81, 128, 133, 239, 94, 152, 103, 79, 170, 101, 73, 88, 38, 158, 151, 133, 124, 27, 241, 31, 84, 57, 101, 0, 228, 179, 75, 70, 36, 140, 142, 83, 126, 22, 124, 57, 26, 51, 76, 221, 206, 130, 18, 234, 107, 10, 202, 241, 41, 201, 29, 216, 202, 158, 125, 156, 50, 230, 198, - 6, 158, 140, 155, 130, 155, 217, 202, 155, 207, 219, 176, 167, 41, 248, 44, 139, 239, 193, 39, 85, 229, 57, 141, 69, 222, 84, 72, 139, 108, 98, 156, 76, 232, 65, 163, 156, 170, 208, 248, 0, 220, 71, 114, 216, 174, 127, 202, 71, 52, 166, 64, 181, 185, 247, 43, 207, 61, 169, 206, 115, 8, 123, 218, 105, 86, 67, 181, 118, 165, 111, 54, 11, 42, 247, 182, 212, 151, 8, 161, 133, 93, 116, 240, 232, 60, 81, 2, 217, 141, 131, 211, 148, 124, 30, 119, 108, 62, 203, 189, - 179, 217, 180, 95, 159, 223, 205, 70, 90, 214, 127, 136, 205, 87, 158, 127, 102, 43, 158, 186, 167, 68, 129, 156, 131, 83, 113, 125, 94, 119, 112, 9, 214, 143, 228, 117, 252, 139, 91, 32, 10, 155, 136, 96, 84, 108, 210, 141, 215, 117, 1, 3, 141, 122, 138, 17, 34, 81, 18, 234, 63, 18, 195, 76, 85, 60, 64, 128, 82, 232, 222, 47, 89, 21, 232, 13, 5, 208, 144, 69, 87, 47, 157, 160, 108, 94, 50, 182, 201, 92, 100, 164, 187, 59, 216, 109, 193, 189, 255, 32, - 75, 49, 190, 114, 161, 166, 143, 230, 73, 54, 97, 188, 137, 186, 44, 229, 32, 70, 202, 193, 126, 89, 146, 178, 106, 55, 231, 111, 34, 189, 220, 155, 62, 214, 66, 108, 234, 20, 184, 210, 93, 13, 201, 130, 231, 127, 3, 200, 218, 118, 110, 218, 221, 194, 42, 62, 202, 141, 98, 148, 65, 202, 1, 54, 77, 103, 225, 121, 226, 55, 79, 24, 137, 121, 10, 19, 129, 210, 126, 156, 227, 152, 30, 164, 5, 254, 2, 113, 200, 36, 113, 83, 114, 88, 114, 168, 75, 243, 246, 149, - 182, 24, 220, 10, 147, 99, 21, 60, 201, 79, 58, 130, 211, 34, 192, 38, 196, 172, 35, 190, 55, 66, 74, 20, 119, 237, 81, 216, 181, 63, 240, 21, 216, 199, 98, 212, 88, 207, 165, 231, 240, 217, 74, 175, 251, 167, 215, 161, 99, 160, 12, 215, 27, 134, 21, 154, 253, 252, 13, 189, 114, 125, 126, 36, 248, 240, 69, 125, 73, 53, 129, 127, 167, 11, 177, 34, 162, 182, 229, 97, 86, 121, 170, 200, 168, 37, 116, 84, 108, 216, 210, 133, 235, 205, 37, 143, 166, 111, 226, 30, - 185, 30, 151, 158, 239, 22, 210, 117, 235, 105, 203, 213, 39, 150, 171, 179, 159, 176, 181, 22, 229, 107, 144, 61, 118, 198, 85, 169, 194, 247, 100, 19, 197, 243, 58, 222, 185, 220, 236, 220, 255, 43, 162, 100, 166, 131, 230, 43, 216, 25, 239, 75, 206, 21, 109, 21, 100, 0, 29, 15, 158, 184, 92, 16, 23, 152, 53, 191, 117, 173, 184, 157, 18, 23, 236, 137, 177, 222, 219, 127, 33, 119, 125, 187, 208, 87, 101, 234, 75, 92, 252, 31, 172, 202, 113, 106, 207, 98, 10, 37, - 235, 70, 233, 182, 235, 144, 167, 35, 227, 68, 238, 31, 8, 249, 95, 51, 46, 6, 251, 143, 51, 101, 111, 244, 179, 117, 8, 197, 254, 241, 56, 145, 238, 15, 141, 163, 39, 120, 230, 253, 55, 198, 89, 78, 240, 206, 204, 19, 141, 170, 39, 57, 49, 161, 14, 226, 148, 11, 179, 37, 38, 87, 95, 77, 176, 86, 14, 106, 222, 51, 39, 207, 134, 148, 1, 60, 108, 60, 54, 206, 56, 100, 184, 209, 188, 98, 117, 151, 139, 214, 16, 79, 220, 199, 142, 155, 6, 253, 146, 75, - 180, 214, 210, 8, 28, 132, 2, 48, 149, 165, 82, 216, 106, 249, 207, 202, 184, 242, 130, 234, 59, 112, 162, 4, 43, 132, 203, 98, 112, 235, 168, 12, 142, 91, 13, 110, 253, 84, 55, 56, 46, 212, 55, 166, 25, 28, 191, 124, 131, 155, 136, 193, 120, 2, 111, 53, 184, 217, 98, 176, 236, 126, 94, 55, 216, 31, 179, 227, 138, 65, 25, 56, 92, 98, 67, 9, 248, 43, 60, 239, 29, 192, 16, 211, 61, 239, 29, 84, 61, 254, 134, 132, 228, 251, 190, 208, 184, 147, 132, 217, - 217, 235, 217, 140, 8, 249, 59, 198, 145, 3, 195, 14, 221, 210, 126, 246, 192, 178, 33, 33, 251, 238, 22, 194, 109, 68, 248, 157, 66, 171, 112, 185, 131, 74, 87, 57, 132, 76, 187, 41, 147, 92, 1, 234, 108, 166, 186, 78, 162, 238, 225, 177, 105, 234, 92, 22, 117, 6, 35, 97, 162, 238, 186, 136, 114, 142, 151, 3, 222, 22, 165, 115, 228, 28, 33, 185, 151, 54, 196, 140, 61, 46, 123, 66, 190, 82, 159, 62, 159, 127, 7, 167, 143, 191, 64, 120, 8, 162, 121, 77, - 1, 113, 87, 157, 113, 209, 163, 121, 129, 225, 77, 167, 32, 237, 238, 119, 84, 185, 247, 67, 36, 156, 210, 188, 5, 105, 183, 250, 244, 0, 220, 244, 49, 43, 10, 52, 0, 95, 41, 16, 129, 182, 185, 128, 6, 160, 121, 127, 83, 129, 37, 0, 91, 231, 137, 70, 22, 128, 227, 254, 164, 7, 96, 171, 80, 223, 71, 3, 48, 166, 121, 91, 49, 0, 207, 96, 0, 106, 5, 52, 0, 53, 195, 136, 29, 66, 52, 70, 2, 176, 7, 31, 73, 226, 162, 214, 37, 90, 19, 148, - 57, 207, 108, 37, 230, 222, 90, 202, 66, 16, 44, 62, 51, 233, 136, 88, 133, 218, 97, 238, 193, 230, 19, 234, 134, 126, 192, 19, 246, 55, 132, 61, 238, 231, 95, 199, 195, 230, 134, 240, 50, 60, 131, 218, 97, 103, 174, 226, 122, 47, 144, 81, 31, 100, 187, 116, 16, 45, 151, 221, 29, 81, 192, 125, 178, 196, 184, 236, 5, 56, 176, 156, 6, 125, 37, 30, 11, 161, 133, 206, 209, 16, 186, 211, 74, 104, 119, 82, 39, 116, 167, 80, 47, 57, 173, 132, 238, 188, 124, 66, - 93, 166, 104, 255, 38, 87, 58, 161, 30, 39, 13, 197, 217, 74, 216, 253, 28, 39, 180, 215, 189, 191, 220, 225, 222, 31, 213, 188, 97, 75, 36, 77, 129, 72, 116, 200, 44, 217, 108, 21, 198, 41, 113, 183, 127, 11, 33, 163, 136, 40, 245, 198, 233, 214, 224, 23, 76, 4, 247, 196, 89, 220, 179, 245, 177, 175, 177, 30, 115, 29, 37, 20, 216, 112, 206, 96, 162, 193, 151, 177, 234, 163, 87, 175, 34, 94, 157, 73, 76, 111, 204, 53, 241, 149, 81, 54, 123, 184, 173, 236, - 92, 234, 239, 25, 188, 166, 2, 216, 75, 247, 164, 164, 45, 13, 61, 120, 2, 235, 14, 62, 251, 149, 137, 171, 156, 58, 90, 159, 132, 222, 30, 213, 147, 248, 67, 18, 139, 100, 143, 68, 120, 168, 32, 227, 223, 241, 21, 174, 95, 194, 110, 119, 224, 223, 115, 96, 211, 74, 99, 167, 102, 84, 177, 179, 199, 26, 59, 47, 244, 235, 177, 179, 71, 168, 175, 74, 139, 157, 61, 151, 31, 59, 139, 137, 1, 119, 229, 164, 199, 78, 245, 112, 177, 99, 27, 38, 118, 186, 180, 202, - 48, 119, 37, 116, 64, 31, 90, 232, 104, 26, 21, 29, 109, 86, 58, 54, 37, 116, 58, 218, 132, 250, 218, 52, 58, 218, 46, 159, 142, 13, 132, 14, 140, 33, 43, 29, 141, 148, 142, 2, 146, 155, 250, 210, 114, 83, 126, 214, 220, 244, 218, 80, 185, 169, 153, 140, 250, 134, 99, 4, 185, 169, 125, 84, 132, 238, 181, 18, 250, 189, 63, 234, 132, 238, 21, 234, 91, 211, 8, 221, 123, 249, 132, 238, 36, 166, 189, 111, 79, 39, 180, 237, 47, 147, 155, 234, 254, 65, 40, 236, - 28, 97, 94, 90, 78, 242, 82, 248, 114, 243, 82, 255, 39, 252, 49, 42, 77, 72, 81, 98, 239, 167, 54, 211, 67, 137, 81, 121, 168, 221, 234, 161, 166, 143, 116, 15, 181, 11, 245, 189, 105, 30, 106, 191, 124, 15, 245, 17, 196, 115, 108, 233, 30, 138, 93, 34, 3, 0, 151, 61, 248, 0, 43, 139, 163, 212, 99, 165, 48, 37, 84, 37, 154, 158, 11, 240, 120, 82, 47, 35, 57, 100, 207, 20, 221, 82, 132, 207, 147, 52, 37, 170, 42, 219, 49, 227, 122, 247, 105, 202, - 246, 89, 202, 190, 186, 107, 53, 239, 118, 184, 50, 150, 54, 38, 38, 246, 0, 109, 42, 254, 48, 34, 172, 41, 93, 170, 178, 13, 198, 80, 189, 205, 154, 178, 109, 150, 210, 188, 14, 228, 182, 193, 149, 177, 4, 160, 182, 52, 163, 8, 2, 234, 42, 245, 136, 35, 58, 48, 111, 109, 53, 92, 136, 50, 17, 202, 183, 1, 14, 227, 202, 97, 67, 237, 17, 245, 173, 47, 213, 19, 159, 237, 97, 194, 61, 178, 135, 125, 70, 241, 177, 139, 94, 200, 77, 155, 240, 32, 64, 47, - 209, 57, 150, 122, 100, 14, 225, 238, 40, 240, 164, 87, 37, 220, 59, 195, 159, 48, 110, 160, 195, 146, 239, 183, 122, 149, 242, 221, 101, 148, 244, 156, 33, 42, 212, 173, 31, 101, 84, 168, 66, 179, 175, 191, 161, 11, 74, 93, 35, 45, 193, 102, 99, 255, 166, 207, 241, 62, 209, 102, 172, 77, 189, 103, 240, 66, 95, 155, 122, 99, 170, 7, 98, 158, 14, 81, 70, 140, 195, 7, 163, 43, 141, 7, 163, 91, 6, 2, 230, 19, 157, 156, 124, 92, 239, 190, 152, 71, 182, 139, - 155, 141, 139, 193, 254, 183, 153, 70, 237, 61, 86, 208, 168, 129, 251, 243, 196, 172, 248, 89, 158, 49, 91, 110, 166, 247, 181, 60, 58, 91, 130, 123, 96, 111, 63, 79, 180, 195, 132, 153, 148, 88, 116, 150, 79, 24, 214, 36, 6, 153, 73, 125, 50, 168, 181, 96, 155, 177, 141, 122, 41, 207, 152, 54, 37, 230, 149, 26, 108, 35, 10, 202, 9, 123, 127, 157, 111, 238, 164, 120, 107, 5, 37, 126, 208, 225, 126, 254, 6, 177, 147, 186, 193, 41, 203, 184, 247, 136, 179, 237, - 148, 147, 109, 167, 156, 22, 251, 107, 71, 101, 255, 222, 76, 251, 63, 208, 237, 223, 75, 224, 47, 78, 179, 127, 239, 149, 218, 95, 77, 237, 31, 155, 110, 127, 205, 208, 246, 151, 139, 173, 100, 54, 219, 155, 71, 101, 123, 123, 134, 237, 75, 98, 186, 237, 237, 4, 250, 134, 52, 219, 219, 175, 212, 246, 70, 98, 251, 244, 49, 233, 182, 55, 89, 108, 183, 19, 219, 221, 248, 52, 8, 118, 119, 104, 189, 131, 89, 239, 216, 210, 16, 159, 8, 241, 176, 254, 90, 33, 221, 74, - 165, 19, 19, 215, 77, 142, 176, 161, 249, 138, 129, 119, 217, 73, 134, 127, 61, 15, 171, 80, 148, 61, 41, 153, 40, 155, 68, 134, 71, 69, 228, 190, 12, 34, 175, 121, 95, 39, 114, 31, 225, 161, 45, 141, 200, 125, 87, 74, 100, 59, 177, 36, 225, 74, 39, 178, 211, 66, 164, 77, 39, 18, 211, 231, 88, 88, 255, 104, 5, 205, 140, 212, 92, 53, 208, 210, 195, 30, 182, 1, 171, 118, 198, 170, 157, 39, 81, 93, 77, 148, 102, 168, 40, 44, 220, 214, 254, 91, 242, 22, - 209, 216, 75, 26, 13, 205, 142, 230, 72, 32, 216, 35, 14, 24, 81, 151, 191, 33, 122, 205, 186, 227, 66, 168, 207, 20, 138, 40, 225, 92, 22, 191, 191, 200, 163, 167, 130, 175, 176, 171, 80, 121, 14, 236, 204, 33, 153, 171, 243, 139, 11, 178, 253, 247, 201, 183, 249, 167, 3, 63, 67, 108, 68, 60, 58, 28, 136, 225, 35, 42, 126, 116, 56, 9, 143, 22, 44, 156, 197, 8, 103, 251, 240, 161, 164, 146, 176, 43, 113, 118, 40, 0, 85, 248, 248, 81, 114, 40, 208, 171, - 151, 131, 136, 210, 197, 2, 36, 226, 52, 3, 4, 255, 65, 113, 228, 1, 210, 153, 17, 32, 255, 125, 70, 15, 144, 78, 130, 53, 145, 22, 32, 157, 87, 26, 32, 131, 196, 216, 72, 78, 122, 128, 92, 160, 158, 13, 227, 111, 19, 182, 78, 224, 235, 19, 205, 59, 64, 151, 228, 236, 129, 185, 114, 134, 175, 223, 194, 108, 85, 2, 139, 186, 1, 92, 149, 68, 245, 31, 80, 156, 225, 75, 26, 108, 4, 103, 187, 215, 79, 208, 188, 93, 108, 53, 210, 131, 139, 28, 17, 98, - 93, 41, 169, 127, 53, 30, 38, 52, 68, 61, 238, 192, 199, 236, 200, 42, 122, 181, 59, 240, 35, 88, 59, 245, 255, 214, 110, 210, 91, 52, 42, 122, 15, 100, 208, 251, 243, 247, 116, 122, 15, 16, 118, 92, 185, 86, 122, 15, 92, 41, 189, 30, 83, 65, 127, 141, 51, 157, 222, 194, 92, 58, 255, 100, 146, 200, 236, 254, 176, 29, 136, 162, 39, 130, 176, 2, 179, 227, 236, 58, 181, 238, 135, 153, 25, 171, 132, 140, 35, 145, 32, 44, 35, 6, 32, 221, 22, 162, 141, 167, - 8, 190, 94, 163, 106, 19, 61, 127, 180, 153, 122, 22, 143, 138, 237, 112, 6, 219, 197, 239, 234, 108, 135, 105, 197, 79, 99, 59, 124, 165, 108, 87, 16, 244, 23, 237, 233, 108, 87, 229, 102, 203, 118, 44, 195, 17, 182, 245, 4, 103, 178, 93, 145, 201, 118, 53, 25, 231, 231, 36, 38, 107, 136, 1, 74, 151, 37, 197, 89, 232, 254, 157, 177, 138, 212, 23, 36, 68, 223, 79, 72, 141, 105, 30, 21, 235, 93, 25, 172, 191, 214, 167, 179, 222, 69, 139, 117, 26, 235, 93, - 87, 92, 172, 9, 250, 128, 45, 163, 88, 91, 88, 207, 33, 172, 111, 246, 135, 199, 10, 214, 115, 25, 235, 185, 195, 178, 222, 74, 198, 25, 79, 98, 115, 231, 8, 89, 111, 163, 236, 234, 229, 210, 162, 10, 112, 184, 159, 115, 124, 97, 90, 218, 73, 37, 244, 165, 54, 63, 159, 215, 151, 218, 120, 62, 31, 242, 47, 193, 18, 39, 177, 95, 12, 95, 178, 104, 129, 234, 99, 236, 151, 86, 32, 119, 156, 127, 203, 199, 194, 133, 107, 88, 141, 255, 131, 166, 89, 183, 102, 188, - 59, 92, 221, 138, 18, 126, 190, 36, 118, 134, 41, 234, 69, 58, 182, 3, 2, 155, 245, 167, 7, 6, 66, 182, 149, 135, 148, 30, 63, 28, 179, 133, 88, 202, 144, 143, 132, 148, 3, 28, 242, 88, 3, 242, 143, 9, 100, 246, 155, 20, 37, 129, 144, 241, 215, 98, 91, 223, 49, 193, 78, 204, 0, 219, 103, 130, 74, 222, 111, 172, 21, 40, 253, 7, 112, 59, 8, 170, 213, 133, 197, 46, 168, 30, 168, 22, 127, 75, 2, 52, 92, 157, 96, 154, 51, 11, 55, 17, 103, 13, - 91, 186, 112, 131, 180, 68, 236, 150, 78, 57, 204, 223, 191, 125, 237, 20, 191, 127, 73, 222, 20, 242, 63, 242, 22, 43, 166, 116, 248, 4, 4, 82, 53, 248, 222, 197, 2, 41, 129, 167, 153, 137, 159, 193, 247, 103, 79, 152, 2, 131, 217, 4, 242, 136, 64, 42, 77, 224, 66, 54, 129, 92, 34, 48, 78, 182, 10, 224, 239, 18, 135, 133, 116, 3, 19, 16, 221, 93, 102, 247, 136, 18, 231, 235, 166, 21, 95, 58, 73, 8, 110, 100, 87, 44, 4, 7, 248, 63, 0, 131, - 63, 15, 30, 18, 254, 252, 234, 144, 53, 4, 113, 237, 132, 255, 213, 19, 98, 3, 35, 249, 237, 111, 167, 199, 224, 66, 54, 67, 56, 0, 143, 9, 160, 127, 190, 44, 101, 114, 92, 152, 205, 32, 167, 48, 8, 22, 228, 19, 158, 61, 37, 250, 22, 81, 107, 98, 78, 98, 77, 218, 239, 101, 132, 77, 44, 104, 7, 249, 191, 63, 131, 89, 115, 12, 179, 26, 14, 89, 195, 20, 205, 154, 40, 81, 179, 222, 57, 13, 159, 255, 79, 219, 211, 199, 71, 85, 36, 57, 147, 15, - 153, 184, 163, 153, 243, 130, 6, 126, 40, 113, 5, 4, 21, 4, 61, 53, 46, 8, 89, 117, 52, 126, 176, 70, 37, 46, 39, 46, 70, 197, 192, 122, 234, 33, 38, 130, 10, 10, 60, 224, 50, 134, 167, 89, 131, 251, 67, 61, 61, 84, 80, 84, 8, 1, 33, 9, 95, 146, 96, 36, 168, 124, 12, 24, 20, 21, 48, 96, 22, 103, 54, 168, 131, 12, 130, 231, 7, 215, 85, 213, 253, 186, 250, 205, 36, 196, 117, 239, 159, 100, 234, 117, 85, 117, 85, 117, 189, 238, 170, 238, - 126, 221, 235, 85, 205, 125, 117, 205, 106, 219, 239, 239, 84, 217, 64, 93, 54, 109, 74, 28, 58, 40, 233, 222, 220, 14, 185, 26, 169, 109, 24, 236, 35, 42, 108, 213, 190, 28, 35, 95, 62, 0, 245, 6, 255, 166, 125, 153, 51, 200, 99, 118, 194, 130, 105, 141, 224, 190, 163, 220, 171, 233, 153, 66, 119, 219, 250, 239, 239, 211, 61, 206, 202, 86, 153, 4, 138, 67, 193, 253, 182, 53, 219, 41, 138, 103, 214, 6, 247, 67, 56, 31, 140, 137, 142, 254, 195, 251, 90, 96, - 7, 77, 191, 224, 254, 232, 86, 180, 236, 156, 15, 112, 104, 243, 177, 206, 162, 158, 104, 133, 1, 231, 74, 46, 52, 147, 166, 159, 207, 193, 95, 206, 76, 90, 248, 114, 85, 136, 51, 105, 67, 183, 203, 153, 180, 176, 98, 159, 175, 217, 103, 214, 14, 223, 47, 2, 201, 15, 91, 50, 64, 232, 249, 178, 2, 154, 72, 155, 239, 8, 221, 172, 40, 11, 152, 103, 249, 225, 179, 12, 80, 166, 222, 71, 74, 18, 202, 72, 141, 82, 108, 77, 217, 159, 153, 57, 171, 15, 236, 27, - 170, 21, 254, 16, 140, 53, 220, 215, 18, 64, 154, 72, 0, 104, 12, 165, 167, 254, 42, 165, 119, 154, 74, 95, 179, 77, 42, 189, 83, 177, 31, 231, 86, 122, 103, 103, 149, 30, 207, 148, 62, 45, 37, 169, 210, 147, 146, 42, 45, 92, 238, 72, 184, 55, 12, 131, 34, 104, 135, 15, 0, 154, 105, 36, 37, 154, 50, 198, 22, 190, 212, 113, 219, 102, 148, 87, 219, 102, 225, 175, 178, 205, 46, 211, 54, 253, 195, 122, 111, 1, 177, 175, 112, 219, 102, 87, 103, 109, 51, 151, - 41, 241, 131, 39, 169, 109, 230, 153, 182, 233, 34, 109, 51, 60, 158, 89, 83, 40, 170, 152, 129, 76, 113, 94, 48, 14, 157, 105, 92, 205, 3, 18, 117, 53, 215, 92, 190, 70, 133, 241, 80, 32, 114, 238, 54, 152, 7, 140, 123, 152, 7, 213, 105, 92, 97, 76, 31, 25, 211, 144, 165, 158, 113, 131, 253, 12, 34, 24, 58, 150, 57, 243, 110, 220, 233, 205, 152, 59, 239, 50, 204, 4, 102, 214, 22, 238, 87, 239, 51, 204, 11, 54, 243, 42, 55, 242, 158, 180, 153, 239, - 32, 25, 33, 251, 134, 67, 71, 160, 111, 152, 212, 132, 67, 43, 239, 75, 35, 148, 179, 30, 128, 127, 145, 129, 13, 32, 2, 97, 237, 212, 88, 145, 80, 3, 244, 76, 184, 117, 23, 58, 184, 86, 140, 25, 8, 45, 194, 76, 127, 51, 70, 98, 244, 188, 133, 85, 226, 58, 242, 225, 34, 134, 22, 99, 181, 180, 124, 198, 163, 4, 97, 129, 66, 167, 150, 163, 172, 150, 175, 112, 44, 137, 97, 146, 189, 209, 163, 89, 101, 103, 48, 35, 196, 48, 228, 154, 127, 88, 249, 226, - 228, 195, 142, 143, 246, 225, 207, 39, 29, 86, 62, 74, 95, 220, 80, 9, 126, 113, 51, 123, 243, 177, 99, 248, 197, 13, 177, 247, 104, 246, 240, 197, 141, 200, 129, 203, 70, 164, 11, 15, 44, 59, 204, 157, 83, 65, 204, 66, 62, 77, 24, 29, 68, 219, 64, 142, 57, 66, 7, 116, 161, 240, 130, 46, 153, 79, 14, 56, 166, 155, 32, 135, 87, 41, 2, 208, 154, 176, 248, 183, 131, 62, 66, 203, 8, 135, 26, 108, 209, 214, 245, 41, 184, 192, 18, 198, 223, 169, 180, 216, - 130, 197, 13, 45, 129, 140, 141, 56, 253, 39, 10, 210, 24, 82, 58, 67, 146, 60, 78, 96, 197, 93, 18, 121, 28, 80, 45, 104, 91, 243, 200, 62, 98, 180, 130, 19, 131, 6, 7, 35, 37, 61, 154, 130, 107, 78, 192, 14, 133, 132, 238, 171, 133, 134, 89, 249, 10, 105, 144, 193, 193, 3, 136, 218, 133, 161, 14, 100, 168, 221, 69, 153, 135, 181, 102, 46, 111, 205, 53, 86, 227, 8, 199, 165, 179, 164, 75, 231, 8, 206, 214, 20, 159, 7, 22, 249, 226, 244, 69, 203, - 130, 70, 28, 88, 152, 193, 103, 34, 75, 122, 158, 151, 193, 94, 226, 153, 43, 40, 248, 21, 238, 230, 247, 148, 220, 1, 43, 37, 132, 85, 192, 140, 94, 43, 6, 202, 117, 225, 242, 160, 143, 108, 50, 40, 12, 70, 178, 22, 172, 144, 19, 98, 241, 134, 136, 47, 180, 109, 80, 67, 104, 120, 252, 88, 80, 244, 28, 126, 120, 149, 253, 158, 210, 229, 138, 215, 200, 132, 26, 225, 189, 22, 132, 71, 194, 86, 99, 150, 91, 35, 145, 71, 172, 164, 99, 39, 154, 103, 11, 58, - 134, 160, 246, 129, 245, 143, 195, 91, 124, 202, 230, 116, 253, 254, 198, 210, 82, 83, 188, 137, 7, 154, 224, 161, 33, 53, 87, 210, 247, 37, 64, 160, 79, 70, 145, 81, 76, 105, 137, 42, 8, 232, 247, 212, 151, 231, 241, 168, 147, 77, 36, 147, 195, 151, 115, 38, 217, 154, 137, 240, 99, 97, 150, 33, 105, 165, 231, 170, 194, 28, 167, 193, 240, 60, 149, 111, 49, 29, 166, 162, 190, 78, 81, 220, 217, 163, 195, 20, 27, 113, 8, 20, 187, 116, 83, 58, 59, 196, 68, 244, - 77, 201, 117, 67, 230, 159, 94, 65, 98, 17, 77, 174, 169, 91, 230, 204, 235, 112, 216, 162, 194, 60, 213, 193, 212, 103, 115, 154, 124, 71, 36, 127, 168, 192, 31, 121, 216, 40, 44, 224, 133, 162, 197, 252, 86, 125, 22, 84, 155, 125, 171, 230, 59, 82, 227, 52, 229, 73, 203, 249, 155, 60, 131, 130, 87, 221, 21, 233, 6, 159, 142, 109, 211, 252, 138, 28, 1, 15, 132, 96, 27, 217, 1, 100, 156, 45, 178, 68, 252, 209, 67, 132, 188, 142, 49, 137, 98, 28, 147, 64, - 84, 188, 32, 69, 87, 60, 62, 161, 193, 252, 212, 96, 104, 153, 37, 185, 92, 145, 73, 188, 193, 100, 29, 131, 100, 33, 63, 161, 68, 86, 51, 84, 87, 195, 143, 3, 113, 53, 91, 137, 108, 182, 23, 14, 66, 179, 77, 127, 31, 71, 111, 15, 27, 85, 98, 52, 170, 44, 130, 6, 20, 156, 203, 11, 3, 161, 224, 252, 80, 225, 66, 57, 84, 138, 127, 217, 30, 125, 14, 15, 68, 188, 90, 126, 15, 56, 156, 136, 75, 131, 177, 193, 226, 245, 155, 57, 14, 91, 146, 234, - 96, 199, 138, 216, 193, 69, 164, 204, 77, 170, 112, 33, 47, 156, 15, 156, 94, 74, 209, 164, 213, 70, 41, 172, 13, 8, 132, 169, 12, 129, 157, 225, 1, 114, 165, 97, 30, 50, 159, 201, 245, 199, 75, 80, 46, 92, 98, 153, 249, 140, 71, 83, 214, 39, 165, 132, 42, 52, 113, 119, 77, 12, 253, 85, 204, 195, 232, 217, 65, 25, 209, 21, 236, 121, 216, 99, 12, 104, 116, 160, 207, 179, 212, 67, 124, 117, 171, 198, 107, 209, 120, 109, 147, 212, 195, 141, 73, 136, 95, 149, - 196, 213, 140, 152, 157, 173, 209, 54, 88, 61, 156, 151, 132, 120, 143, 36, 126, 144, 17, 199, 12, 60, 171, 177, 36, 161, 147, 126, 244, 27, 240, 144, 162, 141, 56, 136, 115, 108, 106, 106, 108, 91, 42, 101, 231, 103, 136, 82, 217, 64, 159, 123, 52, 130, 207, 133, 128, 28, 222, 102, 8, 1, 23, 2, 58, 244, 11, 12, 33, 219, 133, 16, 0, 132, 201, 12, 33, 199, 133, 128, 175, 252, 40, 134, 208, 215, 133, 144, 13, 8, 191, 99, 8, 3, 93, 8, 61, 0, 161, 27, - 67, 96, 199, 76, 36, 25, 2, 34, 215, 125, 13, 246, 26, 136, 67, 96, 158, 193, 139, 22, 114, 69, 166, 8, 175, 134, 15, 243, 196, 24, 142, 248, 48, 158, 148, 5, 16, 74, 33, 40, 15, 193, 60, 2, 196, 83, 4, 21, 148, 90, 22, 112, 42, 254, 163, 168, 121, 160, 172, 121, 219, 87, 52, 156, 150, 116, 179, 173, 154, 13, 56, 142, 50, 81, 97, 88, 131, 113, 214, 75, 103, 68, 97, 57, 59, 130, 34, 122, 140, 122, 230, 149, 48, 14, 139, 192, 28, 207, 184, 249, - 177, 124, 74, 243, 183, 85, 161, 141, 71, 224, 139, 156, 3, 194, 233, 161, 80, 238, 125, 110, 27, 170, 184, 20, 113, 45, 91, 83, 113, 172, 29, 114, 126, 105, 55, 12, 51, 99, 10, 139, 157, 129, 1, 159, 169, 3, 170, 136, 40, 38, 175, 130, 189, 194, 143, 253, 135, 12, 99, 65, 105, 248, 198, 109, 128, 162, 26, 151, 200, 59, 128, 75, 56, 254, 178, 0, 78, 50, 112, 94, 239, 83, 201, 6, 236, 158, 232, 253, 36, 46, 252, 216, 11, 216, 151, 154, 194, 108, 48, 201, - 107, 246, 145, 3, 71, 221, 238, 88, 54, 71, 90, 118, 226, 1, 29, 168, 200, 141, 223, 183, 189, 139, 221, 47, 51, 224, 102, 195, 128, 45, 202, 128, 45, 142, 1, 97, 96, 75, 125, 220, 205, 130, 157, 105, 17, 125, 130, 186, 82, 161, 166, 21, 129, 72, 112, 200, 128, 210, 34, 133, 103, 156, 110, 65, 40, 16, 56, 14, 25, 91, 122, 153, 66, 153, 235, 70, 201, 7, 132, 71, 74, 69, 212, 214, 234, 101, 85, 206, 51, 205, 97, 136, 179, 208, 48, 184, 213, 152, 51, 234, - 246, 132, 32, 231, 15, 75, 169, 35, 249, 198, 50, 131, 28, 53, 141, 145, 223, 6, 175, 192, 87, 239, 178, 32, 39, 238, 97, 163, 133, 109, 117, 157, 227, 145, 95, 253, 254, 20, 81, 225, 104, 198, 80, 253, 9, 192, 101, 68, 174, 67, 30, 57, 192, 216, 86, 191, 57, 84, 119, 85, 161, 62, 215, 139, 80, 85, 16, 212, 118, 170, 249, 60, 155, 171, 147, 184, 51, 255, 121, 216, 193, 111, 229, 189, 203, 195, 31, 167, 123, 47, 136, 200, 100, 64, 212, 120, 232, 12, 26, 149, - 9, 85, 133, 67, 106, 70, 105, 180, 42, 24, 232, 56, 57, 126, 216, 240, 250, 141, 30, 135, 189, 138, 113, 48, 102, 240, 233, 41, 36, 169, 218, 162, 74, 82, 237, 195, 17, 154, 36, 207, 233, 105, 18, 67, 174, 189, 176, 125, 218, 154, 213, 200, 67, 33, 71, 242, 191, 126, 169, 37, 127, 254, 116, 146, 156, 80, 11, 18, 37, 167, 130, 145, 166, 228, 223, 20, 120, 28, 246, 69, 29, 75, 62, 64, 74, 222, 109, 132, 38, 25, 151, 68, 114, 199, 131, 102, 47, 33, 130, 197, - 211, 76, 15, 82, 97, 201, 9, 168, 218, 117, 141, 218, 131, 132, 235, 20, 232, 200, 214, 182, 206, 255, 82, 249, 205, 134, 136, 194, 229, 103, 7, 202, 114, 65, 102, 91, 95, 60, 45, 189, 45, 248, 34, 16, 76, 99, 4, 1, 135, 224, 107, 19, 169, 85, 208, 131, 205, 8, 45, 219, 65, 123, 148, 248, 6, 34, 167, 162, 153, 169, 56, 199, 209, 53, 113, 252, 28, 28, 73, 87, 254, 15, 31, 178, 78, 125, 199, 21, 76, 219, 229, 7, 246, 11, 150, 25, 118, 214, 76, 108, - 185, 180, 29, 240, 175, 95, 216, 187, 81, 12, 111, 27, 242, 124, 94, 156, 207, 16, 45, 53, 236, 177, 6, 69, 238, 248, 152, 21, 223, 207, 231, 131, 35, 6, 52, 215, 128, 114, 13, 40, 203, 128, 254, 205, 128, 242, 13, 104, 151, 1, 5, 12, 200, 103, 64, 243, 59, 168, 239, 54, 3, 218, 105, 64, 105, 6, 148, 99, 64, 35, 12, 104, 182, 1, 173, 49, 160, 69, 6, 116, 175, 1, 121, 190, 228, 80, 216, 40, 155, 97, 64, 63, 26, 80, 137, 1, 249, 13, 40, 219, - 128, 174, 55, 185, 252, 141, 67, 61, 140, 178, 241, 6, 116, 158, 41, 167, 1, 45, 52, 160, 57, 166, 205, 12, 141, 234, 140, 178, 229, 6, 52, 213, 128, 38, 27, 208, 70, 3, 234, 107, 64, 189, 12, 168, 213, 128, 90, 12, 168, 222, 128, 202, 12, 104, 28, 131, 34, 17, 60, 84, 141, 92, 56, 215, 121, 101, 18, 147, 100, 31, 152, 47, 232, 43, 11, 198, 167, 66, 7, 117, 189, 109, 13, 175, 231, 157, 161, 109, 77, 249, 130, 166, 127, 202, 131, 1, 232, 140, 40, 125, - 18, 111, 250, 183, 79, 210, 75, 12, 75, 86, 103, 183, 194, 107, 78, 148, 170, 207, 107, 251, 147, 122, 146, 127, 92, 94, 105, 79, 105, 94, 159, 125, 1, 188, 250, 215, 227, 210, 4, 124, 250, 2, 63, 97, 126, 143, 152, 141, 76, 210, 215, 141, 81, 239, 63, 138, 81, 180, 46, 29, 103, 152, 74, 175, 16, 6, 88, 199, 187, 84, 219, 26, 179, 79, 119, 85, 215, 60, 169, 122, 161, 133, 120, 18, 6, 214, 75, 4, 42, 103, 108, 27, 174, 158, 232, 243, 48, 137, 61, 136, - 111, 178, 187, 195, 100, 247, 95, 140, 221, 36, 167, 183, 199, 162, 107, 116, 145, 121, 236, 101, 245, 62, 57, 211, 38, 240, 164, 53, 54, 239, 211, 184, 101, 28, 119, 211, 62, 61, 232, 60, 203, 144, 42, 146, 48, 68, 164, 18, 134, 196, 82, 67, 171, 113, 76, 130, 83, 28, 66, 212, 220, 183, 19, 178, 27, 200, 77, 139, 69, 224, 80, 28, 42, 140, 193, 124, 15, 203, 217, 126, 123, 135, 199, 161, 225, 231, 75, 214, 170, 85, 27, 196, 26, 87, 164, 177, 170, 61, 238, 12, - 231, 208, 40, 93, 90, 199, 69, 236, 149, 112, 116, 104, 1, 138, 248, 204, 90, 87, 74, 89, 94, 40, 90, 34, 253, 117, 209, 18, 1, 231, 252, 79, 70, 213, 29, 169, 110, 95, 235, 202, 249, 236, 202, 117, 11, 105, 188, 75, 73, 70, 213, 186, 23, 168, 250, 173, 117, 165, 153, 118, 229, 51, 29, 81, 85, 33, 213, 161, 53, 174, 164, 181, 188, 208, 15, 36, 5, 105, 194, 148, 248, 165, 30, 167, 85, 3, 217, 4, 164, 173, 93, 227, 74, 88, 33, 177, 41, 244, 171, 6, - 176, 43, 123, 46, 196, 217, 123, 1, 165, 216, 149, 103, 18, 16, 43, 6, 113, 178, 18, 196, 233, 137, 44, 199, 172, 113, 165, 177, 118, 229, 206, 215, 58, 80, 34, 218, 2, 84, 3, 214, 184, 242, 87, 187, 242, 213, 142, 168, 222, 66, 170, 163, 171, 93, 121, 172, 93, 89, 162, 168, 236, 202, 73, 175, 209, 84, 76, 82, 6, 19, 144, 65, 237, 106, 87, 170, 107, 87, 14, 238, 168, 218, 33, 72, 53, 109, 181, 43, 255, 181, 173, 224, 30, 90, 25, 240, 135, 42, 118, 101, - 166, 56, 15, 138, 155, 166, 238, 19, 160, 87, 240, 237, 157, 192, 23, 191, 137, 243, 75, 206, 251, 62, 7, 206, 103, 175, 118, 37, 206, 182, 117, 100, 183, 238, 115, 203, 135, 139, 30, 225, 249, 221, 84, 149, 47, 212, 20, 250, 232, 199, 67, 243, 173, 70, 191, 218, 118, 108, 112, 172, 64, 142, 59, 86, 185, 50, 109, 209, 203, 237, 113, 113, 236, 182, 167, 93, 142, 76, 247, 60, 228, 55, 115, 149, 43, 49, 183, 173, 139, 28, 129, 146, 190, 17, 62, 164, 27, 190, 202, 149, - 175, 219, 214, 159, 59, 166, 11, 239, 1, 186, 174, 171, 92, 105, 188, 109, 245, 238, 152, 110, 46, 210, 237, 94, 233, 202, 238, 237, 202, 223, 47, 232, 160, 101, 239, 68, 170, 215, 86, 186, 18, 125, 219, 234, 185, 171, 195, 218, 206, 65, 186, 255, 92, 233, 74, 208, 109, 235, 134, 228, 116, 234, 253, 251, 118, 55, 208, 93, 178, 210, 149, 184, 211, 64, 41, 122, 139, 249, 120, 6, 96, 188, 44, 37, 217, 172, 196, 10, 36, 254, 223, 58, 87, 38, 174, 136, 173, 164, 196, 74, - 226, 73, 72, 188, 182, 206, 157, 236, 67, 191, 214, 127, 23, 197, 195, 194, 145, 29, 160, 32, 45, 153, 252, 23, 236, 118, 2, 97, 21, 15, 159, 109, 91, 19, 235, 220, 105, 62, 156, 0, 157, 42, 228, 41, 110, 74, 131, 12, 68, 70, 191, 25, 15, 125, 168, 144, 199, 115, 163, 157, 38, 48, 213, 217, 202, 137, 153, 232, 219, 187, 64, 242, 212, 186, 132, 68, 31, 86, 243, 68, 134, 248, 202, 43, 176, 134, 32, 126, 127, 39, 127, 251, 154, 130, 205, 155, 55, 109, 218, 84, - 30, 108, 62, 178, 55, 20, 110, 136, 164, 138, 84, 190, 60, 216, 210, 208, 146, 146, 26, 108, 241, 214, 227, 135, 26, 133, 45, 176, 12, 13, 84, 153, 181, 195, 191, 179, 43, 159, 122, 5, 123, 185, 214, 226, 80, 218, 181, 138, 39, 70, 9, 240, 19, 26, 51, 49, 235, 236, 189, 43, 93, 73, 177, 33, 120, 200, 101, 23, 219, 186, 167, 214, 53, 187, 208, 118, 141, 122, 56, 215, 101, 170, 239, 94, 166, 45, 172, 197, 131, 131, 173, 165, 103, 8, 14, 39, 122, 224, 24, 187, - 67, 94, 69, 80, 198, 39, 94, 164, 49, 39, 230, 168, 210, 10, 110, 204, 19, 81, 244, 75, 131, 241, 9, 127, 17, 222, 112, 40, 217, 24, 119, 47, 108, 206, 177, 150, 214, 184, 230, 17, 108, 235, 198, 151, 129, 54, 179, 182, 62, 89, 219, 95, 140, 84, 143, 214, 184, 102, 24, 108, 235, 193, 79, 120, 180, 184, 213, 128, 110, 54, 160, 75, 12, 104, 48, 66, 161, 245, 117, 57, 127, 72, 60, 218, 234, 246, 79, 117, 109, 252, 88, 77, 235, 121, 69, 5, 183, 144, 184, 169, - 250, 49, 42, 118, 184, 102, 210, 101, 158, 77, 47, 203, 73, 220, 9, 166, 223, 41, 43, 93, 133, 188, 174, 171, 117, 242, 215, 58, 242, 208, 196, 222, 160, 7, 98, 158, 89, 203, 179, 215, 118, 145, 191, 249, 4, 144, 227, 53, 102, 230, 58, 127, 167, 10, 96, 225, 27, 123, 5, 22, 164, 209, 144, 206, 249, 168, 215, 226, 53, 228, 147, 191, 211, 89, 247, 28, 41, 242, 167, 26, 51, 209, 85, 165, 120, 60, 2, 1, 192, 93, 19, 149, 158, 229, 64, 121, 105, 248, 54, 17, - 11, 149, 12, 71, 45, 108, 169, 201, 146, 0, 15, 89, 44, 9, 42, 172, 190, 78, 69, 61, 36, 130, 218, 210, 211, 219, 227, 113, 206, 206, 23, 129, 215, 12, 178, 244, 196, 157, 216, 123, 192, 228, 90, 219, 105, 206, 123, 66, 188, 244, 161, 249, 113, 38, 135, 51, 219, 194, 230, 125, 112, 184, 27, 34, 173, 240, 210, 78, 176, 194, 67, 31, 41, 133, 50, 103, 60, 129, 76, 95, 93, 97, 38, 27, 10, 3, 45, 65, 0, 88, 66, 19, 150, 22, 218, 214, 244, 143, 105, 25, - 218, 51, 196, 91, 122, 150, 176, 188, 93, 41, 146, 2, 49, 88, 6, 228, 8, 169, 216, 230, 187, 217, 130, 237, 154, 85, 169, 202, 83, 162, 55, 224, 188, 250, 67, 31, 83, 21, 242, 52, 221, 146, 124, 133, 167, 79, 216, 63, 245, 99, 211, 122, 125, 12, 235, 221, 105, 145, 245, 46, 253, 24, 172, 135, 167, 6, 70, 63, 99, 74, 22, 117, 146, 207, 19, 146, 207, 193, 143, 144, 15, 25, 127, 2, 83, 249, 74, 197, 81, 231, 36, 220, 34, 247, 160, 69, 150, 38, 181, 136, - 74, 68, 96, 173, 153, 158, 140, 79, 202, 163, 15, 242, 88, 149, 140, 135, 185, 12, 214, 170, 13, 106, 174, 128, 53, 91, 141, 67, 88, 152, 162, 250, 226, 103, 63, 2, 63, 184, 127, 7, 25, 64, 157, 161, 91, 34, 94, 243, 23, 223, 74, 200, 94, 78, 222, 209, 145, 183, 190, 61, 77, 222, 58, 176, 195, 241, 86, 197, 101, 158, 230, 210, 246, 239, 234, 225, 220, 206, 179, 222, 47, 89, 223, 191, 35, 93, 143, 19, 196, 133, 175, 155, 89, 183, 52, 75, 46, 235, 177, 63, - 112, 173, 251, 169, 30, 96, 193, 14, 208, 249, 145, 102, 165, 115, 170, 163, 243, 27, 203, 92, 121, 144, 109, 117, 111, 54, 5, 235, 111, 8, 214, 93, 10, 182, 163, 217, 241, 49, 197, 133, 229, 75, 109, 55, 225, 10, 68, 134, 122, 135, 207, 105, 10, 202, 149, 67, 191, 60, 44, 80, 233, 68, 164, 245, 188, 225, 232, 181, 166, 2, 99, 89, 204, 152, 209, 85, 131, 205, 123, 205, 160, 219, 150, 165, 238, 212, 200, 186, 119, 42, 73, 122, 39, 67, 96, 89, 80, 178, 184, 105, - 10, 162, 78, 95, 234, 74, 122, 68, 8, 43, 121, 157, 202, 16, 120, 10, 99, 77, 216, 46, 251, 189, 36, 19, 28, 103, 35, 209, 121, 75, 93, 25, 140, 53, 37, 224, 41, 185, 78, 21, 28, 229, 5, 89, 158, 146, 11, 84, 1, 75, 62, 212, 114, 15, 21, 248, 120, 129, 48, 246, 57, 182, 21, 123, 92, 238, 71, 240, 121, 180, 67, 18, 54, 203, 25, 218, 110, 183, 173, 50, 37, 239, 81, 111, 233, 197, 194, 179, 96, 21, 99, 61, 36, 67, 1, 13, 248, 96, 223, 146, - 108, 38, 98, 194, 210, 4, 92, 89, 225, 21, 24, 107, 113, 73, 55, 13, 244, 252, 16, 236, 16, 217, 230, 140, 67, 194, 255, 122, 85, 39, 132, 253, 10, 1, 59, 96, 2, 64, 42, 77, 7, 67, 145, 132, 228, 80, 68, 92, 6, 154, 210, 201, 126, 139, 202, 114, 189, 166, 31, 37, 134, 58, 211, 182, 131, 116, 179, 150, 184, 2, 252, 100, 241, 205, 45, 219, 211, 201, 228, 61, 28, 27, 140, 90, 226, 10, 240, 219, 114, 69, 150, 31, 70, 225, 131, 49, 136, 157, 197, 95, - 79, 40, 5, 95, 128, 94, 167, 167, 232, 23, 128, 40, 11, 92, 214, 75, 12, 50, 246, 110, 3, 249, 246, 87, 185, 98, 122, 219, 170, 194, 90, 236, 202, 191, 111, 77, 135, 179, 219, 2, 24, 168, 211, 67, 168, 209, 182, 46, 14, 235, 62, 2, 27, 120, 85, 88, 57, 107, 98, 208, 241, 8, 86, 243, 120, 149, 43, 250, 79, 134, 122, 3, 162, 142, 168, 114, 133, 244, 201, 80, 123, 33, 106, 191, 42, 87, 64, 95, 135, 187, 198, 147, 224, 199, 195, 128, 255, 253, 98, 87, - 36, 95, 55, 111, 150, 55, 105, 139, 52, 34, 126, 250, 86, 238, 90, 239, 45, 118, 69, 213, 26, 1, 93, 139, 0, 176, 135, 166, 3, 215, 146, 16, 184, 86, 92, 113, 97, 81, 53, 172, 86, 190, 68, 164, 65, 31, 54, 103, 26, 239, 207, 8, 191, 162, 221, 230, 116, 130, 202, 90, 185, 62, 63, 119, 92, 242, 189, 67, 7, 183, 130, 74, 53, 85, 78, 80, 137, 237, 90, 188, 5, 133, 131, 35, 143, 5, 116, 249, 100, 57, 105, 233, 239, 21, 233, 131, 248, 127, 223, 162, - 222, 235, 20, 56, 104, 136, 64, 117, 240, 47, 48, 211, 113, 167, 94, 53, 173, 226, 17, 38, 156, 166, 174, 185, 120, 75, 119, 106, 46, 178, 227, 38, 143, 39, 170, 236, 142, 95, 249, 243, 80, 168, 174, 91, 92, 131, 237, 245, 182, 117, 112, 49, 143, 30, 133, 73, 55, 235, 176, 22, 39, 51, 159, 123, 84, 79, 200, 94, 187, 133, 13, 176, 68, 169, 162, 192, 182, 107, 213, 147, 190, 237, 243, 90, 206, 120, 253, 188, 153, 141, 168, 68, 153, 219, 177, 18, 99, 183, 160, 159, - 111, 86, 190, 227, 85, 0, 248, 78, 193, 102, 30, 240, 222, 42, 122, 195, 197, 102, 60, 41, 233, 4, 234, 174, 77, 212, 118, 108, 77, 205, 182, 252, 143, 234, 38, 188, 107, 51, 83, 147, 248, 56, 83, 217, 163, 213, 147, 252, 206, 114, 206, 101, 156, 51, 54, 115, 21, 208, 177, 137, 219, 200, 228, 170, 59, 249, 31, 210, 13, 90, 100, 70, 143, 119, 108, 50, 82, 144, 27, 25, 8, 135, 77, 201, 98, 178, 20, 1, 161, 64, 187, 89, 14, 137, 182, 229, 77, 30, 78, 182, - 139, 12, 138, 138, 246, 125, 147, 199, 141, 38, 178, 49, 197, 181, 24, 209, 39, 188, 201, 3, 79, 154, 193, 212, 65, 165, 36, 247, 39, 9, 21, 239, 71, 242, 11, 223, 76, 136, 57, 253, 101, 65, 216, 135, 28, 167, 69, 4, 60, 127, 92, 206, 31, 111, 255, 64, 147, 176, 104, 84, 86, 146, 176, 54, 26, 249, 13, 86, 209, 250, 30, 239, 184, 194, 111, 36, 196, 161, 10, 1, 59, 46, 2, 192, 242, 154, 14, 58, 46, 9, 201, 142, 139, 184, 176, 144, 19, 71, 108, 114, - 123, 42, 155, 231, 57, 78, 39, 21, 185, 15, 181, 41, 54, 164, 187, 224, 141, 132, 32, 180, 152, 75, 87, 236, 72, 87, 108, 72, 87, 108, 72, 71, 92, 170, 147, 74, 71, 101, 117, 237, 74, 167, 154, 103, 43, 236, 105, 178, 230, 188, 238, 10, 32, 109, 56, 100, 38, 110, 238, 81, 123, 142, 161, 178, 144, 82, 31, 63, 38, 216, 230, 169, 249, 47, 196, 157, 185, 209, 81, 90, 188, 122, 151, 189, 158, 16, 94, 42, 4, 84, 154, 0, 80, 90, 211, 149, 246, 113, 32, 153, - 245, 17, 23, 190, 125, 108, 14, 156, 47, 41, 163, 58, 42, 101, 97, 167, 218, 196, 211, 252, 51, 118, 8, 84, 206, 162, 206, 232, 45, 169, 24, 81, 203, 61, 40, 97, 181, 7, 37, 44, 247, 160, 88, 71, 179, 30, 2, 242, 67, 140, 156, 197, 159, 209, 211, 82, 245, 220, 220, 205, 10, 193, 216, 214, 21, 183, 203, 251, 65, 179, 37, 95, 174, 206, 172, 201, 243, 13, 241, 150, 156, 129, 243, 76, 138, 222, 136, 99, 227, 195, 30, 122, 13, 254, 78, 28, 172, 138, 125, 191, - 152, 61, 104, 240, 45, 211, 128, 5, 178, 209, 194, 20, 103, 107, 121, 219, 88, 133, 96, 4, 162, 49, 55, 107, 187, 18, 171, 60, 197, 27, 102, 123, 102, 199, 138, 102, 18, 13, 230, 23, 85, 29, 132, 164, 249, 39, 189, 237, 155, 120, 102, 243, 88, 59, 54, 236, 177, 74, 85, 192, 34, 87, 190, 241, 21, 238, 16, 107, 74, 235, 5, 255, 34, 63, 52, 209, 222, 2, 34, 96, 65, 106, 168, 48, 2, 52, 1, 143, 222, 44, 107, 211, 87, 114, 179, 97, 63, 153, 36, 96, - 145, 235, 134, 224, 39, 34, 128, 140, 23, 247, 247, 141, 132, 143, 177, 5, 226, 104, 175, 135, 241, 102, 97, 107, 113, 168, 240, 211, 166, 224, 46, 145, 15, 120, 5, 79, 85, 13, 169, 28, 1, 202, 250, 13, 233, 176, 65, 205, 154, 114, 224, 24, 236, 58, 34, 6, 44, 126, 141, 84, 108, 224, 98, 243, 89, 228, 20, 218, 147, 81, 58, 145, 2, 152, 159, 54, 192, 168, 213, 124, 140, 181, 17, 191, 191, 104, 41, 190, 211, 244, 156, 71, 185, 133, 184, 161, 36, 5, 119, 202, - 181, 239, 7, 118, 65, 22, 8, 124, 60, 52, 218, 60, 65, 219, 238, 218, 107, 113, 59, 43, 32, 55, 222, 66, 24, 240, 48, 73, 237, 97, 210, 25, 187, 207, 154, 173, 198, 188, 132, 205, 80, 145, 219, 96, 19, 153, 117, 230, 2, 87, 28, 75, 115, 187, 240, 145, 86, 28, 238, 155, 89, 143, 43, 98, 13, 17, 95, 70, 24, 103, 72, 19, 187, 174, 44, 228, 179, 247, 29, 222, 199, 124, 50, 223, 21, 237, 106, 4, 236, 99, 8, 128, 62, 70, 211, 65, 31, 35, 33, 217, - 177, 18, 23, 190, 83, 237, 74, 60, 92, 203, 135, 47, 33, 149, 150, 25, 146, 219, 229, 239, 54, 30, 231, 37, 196, 173, 132, 49, 108, 96, 226, 192, 175, 83, 106, 69, 19, 210, 243, 138, 78, 115, 206, 162, 37, 225, 43, 26, 225, 205, 43, 209, 159, 4, 16, 31, 54, 215, 28, 157, 225, 241, 28, 87, 76, 216, 57, 3, 56, 9, 77, 143, 52, 226, 101, 223, 112, 92, 30, 89, 174, 137, 9, 18, 100, 161, 43, 144, 119, 174, 100, 208, 227, 69, 62, 108, 10, 178, 150, 174, - 231, 109, 121, 210, 43, 233, 238, 217, 104, 133, 128, 109, 73, 0, 180, 165, 166, 131, 182, 148, 144, 76, 107, 137, 11, 191, 250, 105, 117, 23, 221, 150, 84, 90, 239, 178, 248, 247, 235, 59, 209, 150, 173, 212, 150, 196, 129, 221, 232, 20, 29, 133, 252, 253, 56, 30, 81, 105, 152, 247, 124, 89, 180, 39, 242, 103, 70, 205, 174, 92, 138, 158, 142, 212, 217, 158, 204, 153, 126, 220, 168, 77, 24, 45, 157, 150, 80, 248, 4, 239, 68, 225, 182, 121, 240, 145, 11, 215, 83, 79, - 68, 236, 34, 188, 3, 141, 149, 151, 198, 172, 45, 105, 199, 231, 27, 42, 161, 233, 255, 52, 201, 243, 243, 134, 116, 71, 192, 216, 47, 16, 48, 32, 152, 100, 73, 1, 141, 19, 75, 100, 40, 200, 122, 152, 120, 3, 23, 251, 40, 23, 251, 192, 241, 235, 145, 87, 143, 56, 50, 11, 134, 231, 54, 192, 180, 131, 232, 175, 167, 40, 166, 236, 70, 168, 72, 75, 61, 175, 142, 93, 78, 85, 158, 98, 29, 61, 11, 78, 122, 165, 18, 118, 17, 84, 121, 48, 75, 173, 176, 60, - 240, 0, 217, 229, 162, 6, 156, 214, 59, 202, 90, 152, 93, 228, 20, 29, 156, 14, 154, 30, 24, 28, 12, 100, 206, 232, 138, 191, 157, 215, 166, 245, 48, 163, 97, 151, 59, 69, 187, 164, 163, 87, 28, 203, 156, 249, 179, 87, 123, 69, 223, 148, 95, 233, 21, 167, 27, 250, 230, 166, 252, 51, 188, 226, 189, 117, 218, 43, 242, 126, 129, 128, 191, 192, 43, 246, 172, 227, 98, 231, 167, 252, 106, 175, 232, 202, 100, 102, 183, 72, 161, 163, 220, 166, 10, 216, 181, 81, 145, 218, - 183, 185, 4, 69, 110, 71, 233, 203, 219, 148, 251, 1, 187, 69, 42, 122, 97, 170, 246, 131, 147, 82, 219, 247, 3, 118, 159, 86, 244, 24, 235, 19, 6, 254, 218, 214, 239, 105, 40, 49, 233, 159, 210, 250, 31, 172, 133, 85, 218, 108, 185, 43, 57, 243, 201, 77, 204, 93, 167, 254, 255, 120, 67, 120, 45, 70, 97, 100, 202, 210, 7, 85, 109, 236, 74, 44, 252, 244, 40, 11, 102, 246, 255, 1, 223, 248, 126, 13, 91, 192, 33, 214, 236, 230, 171, 232, 125, 76, 193, 185, - 46, 215, 121, 64, 21, 176, 27, 177, 34, 147, 215, 112, 171, 87, 187, 93, 231, 50, 103, 200, 210, 37, 34, 10, 134, 73, 187, 200, 191, 194, 222, 37, 97, 217, 190, 99, 156, 145, 139, 73, 82, 254, 51, 124, 247, 44, 125, 232, 31, 82, 245, 100, 82, 149, 59, 31, 187, 208, 42, 58, 157, 153, 160, 236, 151, 180, 101, 146, 170, 94, 89, 141, 85, 125, 199, 170, 98, 183, 97, 177, 169, 103, 57, 66, 186, 238, 213, 202, 211, 231, 234, 171, 175, 125, 211, 81, 248, 152, 17, 127, - 164, 172, 226, 1, 197, 251, 207, 225, 80, 202, 239, 211, 82, 8, 24, 80, 16, 0, 1, 133, 166, 131, 128, 66, 66, 50, 1, 37, 46, 236, 182, 171, 232, 59, 44, 56, 164, 210, 152, 203, 58, 53, 171, 58, 17, 80, 52, 83, 64, 65, 28, 216, 85, 93, 209, 187, 188, 30, 119, 30, 75, 72, 236, 230, 170, 232, 80, 244, 67, 122, 206, 46, 192, 74, 76, 142, 90, 240, 67, 86, 216, 241, 35, 177, 217, 181, 85, 27, 130, 123, 33, 75, 96, 201, 209, 239, 227, 116, 46, 4, - 161, 178, 203, 168, 68, 114, 180, 79, 52, 18, 36, 71, 237, 37, 109, 87, 173, 34, 79, 39, 90, 118, 235, 20, 124, 151, 7, 31, 160, 191, 241, 28, 26, 118, 56, 44, 145, 101, 97, 110, 53, 162, 151, 220, 81, 26, 80, 119, 134, 65, 130, 35, 228, 136, 173, 76, 119, 62, 144, 11, 192, 71, 181, 205, 71, 152, 33, 216, 77, 84, 176, 102, 64, 15, 249, 109, 88, 196, 164, 251, 74, 150, 175, 16, 82, 46, 71, 106, 78, 246, 201, 237, 226, 149, 56, 255, 53, 23, 199, 51, - 118, 99, 142, 245, 219, 58, 215, 12, 233, 21, 99, 245, 12, 233, 174, 58, 77, 197, 174, 168, 146, 115, 88, 137, 219, 110, 174, 198, 90, 198, 213, 114, 127, 245, 35, 117, 1, 175, 83, 33, 160, 191, 18, 0, 254, 170, 233, 192, 95, 37, 36, 3, 96, 226, 194, 110, 190, 138, 174, 66, 253, 7, 214, 153, 43, 229, 195, 20, 106, 17, 175, 112, 77, 173, 75, 201, 175, 139, 181, 146, 71, 106, 245, 14, 131, 27, 20, 249, 184, 14, 201, 51, 152, 141, 234, 160, 80, 180, 52, 164, - 92, 68, 59, 222, 108, 50, 45, 62, 191, 105, 42, 249, 18, 230, 9, 104, 240, 15, 254, 138, 3, 13, 191, 230, 203, 71, 59, 84, 244, 132, 255, 23, 119, 235, 57, 221, 139, 106, 53, 85, 89, 7, 205, 164, 114, 206, 121, 136, 31, 170, 81, 115, 241, 191, 113, 22, 129, 239, 70, 30, 21, 92, 249, 174, 53, 230, 34, 112, 47, 15, 95, 4, 126, 225, 110, 26, 49, 195, 53, 108, 194, 154, 184, 176, 123, 137, 96, 225, 155, 30, 206, 237, 60, 235, 119, 37, 235, 210, 26, 54, - 77, 79, 92, 140, 43, 139, 146, 206, 212, 175, 5, 214, 65, 159, 90, 239, 128, 77, 1, 164, 235, 9, 164, 235, 159, 108, 107, 250, 51, 56, 116, 113, 86, 62, 186, 167, 239, 130, 21, 142, 165, 245, 182, 240, 19, 153, 193, 27, 87, 48, 109, 137, 15, 187, 227, 167, 109, 148, 122, 88, 215, 89, 230, 23, 51, 230, 99, 87, 48, 125, 137, 207, 198, 118, 245, 85, 142, 179, 25, 118, 61, 88, 79, 207, 193, 33, 136, 219, 248, 242, 229, 166, 141, 79, 51, 108, 60, 126, 12, 217, - 248, 95, 24, 57, 187, 231, 7, 175, 177, 73, 230, 65, 163, 87, 164, 235, 47, 11, 169, 51, 63, 11, 137, 217, 109, 62, 209, 229, 88, 5, 61, 111, 225, 26, 248, 155, 242, 178, 104, 120, 23, 191, 114, 134, 193, 175, 225, 62, 187, 242, 134, 229, 184, 108, 185, 177, 161, 37, 213, 43, 254, 164, 192, 165, 83, 61, 212, 98, 101, 65, 118, 187, 56, 57, 14, 78, 15, 216, 68, 25, 134, 178, 176, 26, 166, 44, 164, 160, 131, 137, 157, 96, 107, 214, 114, 102, 98, 18, 48, 118, - 92, 151, 186, 103, 57, 216, 232, 230, 183, 92, 91, 39, 110, 178, 173, 243, 43, 113, 176, 227, 102, 255, 124, 153, 234, 50, 100, 11, 247, 190, 75, 119, 25, 51, 223, 98, 238, 67, 196, 236, 186, 159, 182, 2, 245, 144, 95, 47, 148, 200, 113, 40, 227, 120, 225, 91, 76, 33, 34, 14, 164, 29, 79, 161, 103, 97, 19, 137, 53, 125, 153, 82, 40, 211, 81, 104, 244, 211, 56, 78, 242, 234, 79, 94, 230, 234, 3, 103, 221, 169, 171, 95, 190, 140, 41, 68, 196, 125, 77, 133, - 232, 97, 78, 135, 28, 255, 135, 113, 188, 115, 25, 83, 136, 136, 7, 30, 87, 161, 141, 203, 112, 254, 101, 169, 82, 40, 157, 20, 18, 157, 143, 253, 23, 28, 38, 121, 245, 151, 45, 229, 246, 244, 59, 82, 68, 239, 96, 227, 223, 82, 166, 23, 241, 96, 55, 12, 193, 165, 171, 244, 48, 175, 51, 140, 207, 100, 234, 89, 75, 153, 122, 196, 163, 224, 184, 234, 69, 97, 119, 133, 181, 189, 90, 169, 151, 230, 180, 87, 85, 5, 142, 142, 92, 138, 209, 213, 46, 119, 121, 132, - 233, 149, 198, 245, 34, 226, 113, 102, 123, 209, 195, 162, 14, 57, 190, 200, 56, 46, 171, 102, 10, 17, 241, 248, 118, 21, 82, 157, 86, 54, 42, 180, 251, 41, 28, 27, 121, 85, 246, 18, 151, 107, 28, 44, 210, 85, 93, 93, 173, 169, 216, 29, 63, 230, 104, 135, 139, 127, 61, 100, 61, 213, 72, 49, 124, 9, 15, 75, 74, 145, 190, 140, 215, 170, 16, 48, 44, 33, 0, 63, 245, 113, 232, 32, 44, 145, 144, 12, 75, 136, 75, 5, 187, 55, 229, 32, 90, 224, 225, 170, - 196, 186, 140, 235, 142, 20, 2, 214, 69, 0, 212, 165, 233, 160, 46, 9, 25, 117, 177, 171, 130, 228, 17, 41, 207, 46, 81, 14, 225, 39, 135, 232, 33, 194, 145, 124, 70, 194, 46, 8, 106, 43, 20, 227, 170, 172, 3, 6, 163, 63, 227, 111, 47, 244, 158, 124, 115, 157, 66, 73, 21, 113, 205, 122, 5, 134, 240, 75, 41, 205, 182, 218, 117, 249, 85, 15, 182, 110, 234, 236, 255, 133, 45, 45, 214, 145, 69, 124, 217, 240, 7, 27, 135, 70, 110, 13, 133, 128, 214, 32, - 0, 172, 161, 233, 96, 217, 80, 66, 114, 118, 155, 184, 240, 139, 135, 174, 177, 173, 158, 85, 202, 20, 39, 73, 83, 56, 94, 78, 248, 236, 50, 162, 182, 110, 229, 184, 60, 168, 138, 194, 46, 119, 77, 140, 110, 193, 88, 182, 117, 138, 141, 226, 173, 151, 75, 222, 4, 226, 2, 55, 252, 132, 71, 55, 45, 86, 82, 116, 33, 41, 174, 182, 173, 1, 255, 199, 217, 179, 64, 71, 85, 36, 59, 33, 51, 97, 116, 163, 137, 24, 125, 89, 54, 62, 130, 70, 15, 32, 98, 130, - 168, 248, 20, 12, 46, 147, 128, 124, 132, 133, 128, 202, 162, 176, 66, 248, 179, 252, 130, 128, 36, 16, 110, 6, 114, 185, 204, 154, 4, 2, 138, 186, 130, 11, 111, 17, 226, 123, 168, 152, 160, 162, 38, 24, 51, 176, 7, 247, 69, 14, 186, 81, 145, 147, 221, 131, 190, 193, 100, 61, 113, 69, 205, 34, 194, 187, 85, 213, 125, 187, 122, 230, 14, 113, 159, 231, 72, 166, 111, 87, 85, 87, 87, 85, 119, 245, 183, 26, 203, 104, 225, 149, 70, 76, 27, 252, 84, 13, 31, 215, - 45, 124, 68, 141, 4, 166, 190, 228, 52, 211, 51, 13, 168, 107, 34, 211, 202, 201, 244, 123, 137, 11, 151, 0, 34, 110, 0, 40, 92, 74, 0, 151, 10, 15, 132, 43, 82, 194, 212, 136, 74, 7, 19, 214, 35, 14, 8, 236, 235, 235, 44, 111, 101, 44, 239, 173, 97, 253, 0, 145, 233, 212, 4, 203, 232, 243, 231, 124, 244, 225, 176, 148, 56, 168, 60, 100, 248, 247, 241, 198, 116, 200, 66, 127, 201, 223, 138, 144, 0, 88, 67, 74, 64, 13, 21, 30, 52, 38, 145, 18, - 53, 36, 42, 236, 221, 159, 51, 127, 70, 150, 91, 247, 73, 221, 249, 157, 163, 183, 4, 171, 189, 109, 52, 127, 223, 165, 70, 174, 195, 167, 210, 168, 234, 205, 125, 106, 102, 241, 144, 164, 147, 249, 211, 233, 204, 23, 116, 150, 238, 99, 66, 37, 42, 218, 195, 64, 103, 89, 149, 178, 227, 10, 85, 186, 145, 23, 224, 72, 130, 97, 237, 149, 21, 189, 204, 25, 253, 207, 218, 136, 94, 146, 51, 248, 111, 123, 117, 6, 51, 52, 6, 239, 249, 53, 49, 120, 124, 47, 243, 39, - 68, 133, 189, 250, 211, 182, 72, 126, 204, 253, 233, 164, 31, 18, 164, 31, 135, 35, 0, 198, 134, 34, 17, 243, 73, 254, 196, 6, 7, 63, 65, 209, 68, 124, 156, 47, 158, 191, 145, 53, 223, 131, 180, 42, 95, 148, 53, 191, 220, 169, 249, 2, 19, 29, 40, 103, 239, 186, 23, 117, 246, 122, 107, 236, 21, 79, 33, 246, 90, 94, 100, 53, 39, 42, 236, 33, 163, 182, 98, 249, 113, 218, 79, 39, 189, 83, 144, 46, 134, 173, 72, 129, 206, 158, 235, 17, 134, 96, 119, 63, - 115, 234, 97, 180, 141, 91, 184, 12, 116, 69, 92, 49, 200, 78, 121, 39, 66, 23, 150, 163, 3, 229, 143, 193, 216, 109, 249, 218, 61, 188, 101, 31, 122, 88, 181, 236, 230, 61, 10, 75, 123, 156, 104, 59, 161, 184, 30, 163, 189, 3, 139, 250, 97, 3, 122, 73, 142, 180, 239, 143, 186, 8, 174, 209, 68, 176, 240, 97, 170, 215, 170, 61, 10, 157, 61, 176, 227, 118, 40, 242, 24, 130, 86, 34, 232, 14, 46, 2, 62, 217, 240, 140, 157, 190, 96, 102, 83, 238, 37, 142, - 21, 5, 145, 204, 253, 72, 102, 79, 52, 153, 132, 159, 76, 102, 40, 146, 73, 68, 50, 251, 255, 255, 220, 124, 255, 71, 32, 115, 104, 61, 58, 204, 127, 157, 140, 212, 194, 126, 36, 243, 249, 110, 238, 40, 138, 144, 104, 61, 215, 137, 4, 192, 110, 148, 18, 208, 186, 20, 30, 56, 10, 145, 18, 94, 152, 168, 176, 7, 125, 216, 225, 29, 202, 107, 142, 50, 199, 88, 27, 233, 129, 220, 37, 106, 220, 253, 37, 136, 238, 146, 115, 151, 200, 185, 75, 116, 184, 75, 212, 184, - 75, 212, 184, 35, 42, 173, 174, 220, 81, 94, 164, 75, 238, 150, 253, 39, 112, 87, 176, 139, 115, 119, 23, 226, 118, 112, 238, 36, 0, 114, 71, 9, 224, 78, 225, 1, 119, 34, 37, 184, 35, 42, 157, 174, 220, 81, 158, 39, 41, 30, 119, 242, 146, 249, 71, 112, 254, 192, 120, 166, 12, 93, 34, 127, 110, 129, 162, 129, 4, 106, 140, 122, 111, 216, 51, 110, 216, 196, 17, 96, 32, 77, 129, 179, 16, 211, 203, 108, 8, 21, 212, 28, 28, 237, 161, 171, 80, 112, 100, 13, - 218, 247, 117, 140, 20, 123, 60, 71, 24, 85, 236, 189, 236, 41, 8, 63, 124, 151, 236, 76, 175, 116, 58, 211, 76, 164, 145, 206, 159, 214, 104, 254, 131, 222, 220, 175, 215, 154, 123, 205, 36, 106, 238, 214, 46, 214, 153, 18, 21, 246, 250, 14, 184, 80, 250, 152, 249, 211, 73, 55, 11, 210, 217, 187, 152, 11, 37, 42, 217, 73, 93, 117, 148, 43, 96, 227, 223, 24, 242, 2, 215, 253, 16, 3, 125, 36, 231, 64, 2, 160, 238, 41, 1, 186, 87, 120, 160, 123, 145, 18, - 186, 39, 42, 236, 113, 28, 212, 253, 12, 228, 142, 242, 70, 196, 213, 189, 228, 238, 19, 216, 83, 48, 242, 53, 238, 158, 95, 135, 158, 144, 115, 151, 207, 185, 203, 119, 184, 203, 215, 184, 203, 215, 184, 35, 42, 15, 38, 185, 89, 38, 229, 77, 235, 146, 187, 123, 144, 187, 4, 132, 158, 205, 249, 121, 121, 167, 174, 175, 171, 53, 125, 157, 152, 72, 250, 90, 251, 130, 66, 103, 47, 253, 184, 149, 116, 28, 65, 123, 237, 228, 114, 216, 86, 138, 174, 144, 151, 43, 1, 80, - 14, 148, 0, 57, 40, 60, 144, 131, 72, 9, 57, 16, 21, 246, 140, 77, 91, 223, 144, 241, 63, 59, 217, 248, 223, 17, 11, 129, 150, 119, 41, 150, 27, 145, 217, 30, 59, 56, 179, 95, 174, 69, 247, 200, 153, 149, 0, 200, 44, 37, 112, 178, 177, 131, 51, 43, 82, 130, 89, 162, 242, 148, 171, 210, 40, 111, 71, 151, 220, 109, 216, 9, 220, 45, 122, 158, 115, 55, 26, 113, 247, 112, 238, 36, 0, 114, 71, 9, 224, 78, 225, 1, 119, 34, 37, 184, 35, 42, 251, 93, - 185, 163, 188, 131, 93, 114, 119, 102, 7, 112, 87, 165, 113, 247, 95, 107, 208, 141, 113, 238, 170, 56, 119, 85, 14, 119, 85, 26, 119, 85, 26, 119, 68, 229, 136, 43, 119, 148, 215, 28, 151, 59, 233, 171, 71, 33, 119, 169, 8, 221, 18, 211, 127, 198, 56, 229, 144, 177, 118, 62, 153, 250, 206, 193, 30, 215, 17, 205, 185, 231, 129, 224, 243, 193, 174, 239, 146, 54, 35, 100, 17, 248, 12, 231, 76, 191, 3, 55, 105, 66, 105, 187, 71, 189, 48, 182, 11, 97, 71, 34, - 108, 170, 83, 35, 10, 229, 16, 204, 250, 225, 226, 197, 66, 179, 58, 19, 66, 152, 7, 210, 204, 96, 246, 15, 240, 56, 58, 252, 75, 187, 213, 169, 120, 222, 47, 56, 72, 132, 91, 159, 192, 104, 201, 227, 255, 41, 117, 72, 5, 178, 231, 28, 134, 126, 156, 178, 51, 29, 245, 124, 246, 156, 212, 67, 74, 217, 102, 148, 48, 65, 244, 137, 129, 64, 5, 82, 2, 20, 168, 16, 139, 30, 145, 72, 217, 209, 72, 48, 59, 253, 249, 239, 249, 24, 118, 247, 120, 53, 134, 77, - 254, 189, 79, 129, 218, 186, 15, 102, 252, 160, 88, 148, 103, 255, 219, 38, 165, 212, 161, 8, 82, 234, 66, 89, 152, 47, 8, 102, 139, 154, 15, 207, 74, 133, 197, 123, 115, 52, 144, 63, 42, 201, 15, 202, 138, 188, 100, 19, 14, 35, 77, 15, 171, 88, 174, 148, 50, 230, 148, 54, 122, 212, 131, 234, 81, 186, 241, 35, 123, 47, 65, 255, 207, 98, 156, 166, 90, 5, 105, 209, 186, 201, 136, 213, 77, 186, 174, 155, 186, 231, 20, 173, 113, 177, 186, 121, 191, 30, 42, 70, - 217, 15, 58, 217, 122, 181, 139, 159, 141, 95, 237, 241, 227, 84, 181, 107, 159, 85, 69, 77, 227, 182, 170, 213, 149, 13, 29, 50, 145, 183, 247, 160, 115, 231, 193, 82, 89, 60, 151, 144, 241, 245, 246, 104, 51, 33, 120, 117, 71, 84, 66, 160, 153, 80, 2, 204, 68, 33, 130, 153, 16, 210, 138, 104, 36, 48, 147, 234, 103, 184, 153, 84, 62, 160, 204, 228, 243, 103, 124, 10, 20, 186, 136, 118, 65, 136, 159, 253, 111, 203, 115, 72, 56, 190, 236, 23, 154, 47, 123, 249, - 1, 106, 224, 7, 158, 241, 201, 56, 221, 146, 142, 118, 61, 181, 157, 29, 38, 212, 236, 161, 19, 249, 120, 14, 93, 75, 5, 199, 112, 107, 174, 233, 177, 38, 145, 166, 155, 196, 46, 70, 142, 221, 6, 96, 86, 81, 247, 54, 232, 157, 32, 118, 120, 88, 159, 154, 195, 180, 241, 44, 214, 131, 128, 246, 184, 1, 161, 66, 114, 28, 133, 40, 220, 162, 25, 18, 111, 191, 11, 30, 232, 100, 193, 118, 174, 147, 127, 142, 81, 58, 25, 15, 27, 221, 18, 84, 53, 93, 34, 199, - 239, 155, 78, 139, 54, 99, 65, 83, 153, 113, 26, 110, 208, 143, 118, 54, 232, 237, 62, 98, 172, 178, 230, 200, 211, 122, 35, 166, 18, 234, 153, 248, 99, 219, 49, 115, 82, 195, 145, 207, 183, 158, 226, 78, 234, 12, 185, 23, 94, 103, 9, 128, 178, 162, 4, 200, 74, 225, 129, 147, 18, 41, 225, 164, 136, 10, 187, 121, 192, 156, 20, 229, 241, 200, 62, 113, 238, 154, 237, 43, 36, 155, 236, 63, 208, 125, 99, 47, 248, 52, 176, 223, 111, 173, 79, 177, 90, 187, 77, 233, - 190, 2, 75, 131, 108, 30, 115, 79, 66, 96, 101, 40, 1, 149, 81, 136, 69, 83, 36, 82, 106, 52, 18, 104, 253, 220, 54, 174, 245, 218, 209, 74, 235, 83, 96, 223, 92, 130, 10, 57, 16, 33, 233, 111, 218, 254, 195, 193, 87, 59, 19, 167, 70, 171, 237, 130, 244, 167, 216, 200, 159, 112, 51, 185, 144, 98, 135, 253, 165, 88, 232, 58, 135, 40, 174, 243, 54, 109, 117, 52, 90, 16, 50, 110, 90, 163, 187, 44, 153, 139, 18, 160, 132, 142, 84, 148, 233, 164, 68, 53, - 136, 132, 115, 121, 77, 197, 54, 160, 140, 193, 238, 138, 148, 122, 250, 108, 27, 171, 85, 18, 21, 168, 110, 49, 236, 220, 134, 183, 24, 122, 219, 146, 216, 170, 213, 98, 93, 9, 247, 72, 109, 107, 66, 198, 212, 81, 30, 142, 57, 139, 48, 127, 129, 123, 231, 189, 144, 58, 225, 72, 127, 212, 54, 42, 100, 44, 212, 113, 110, 227, 56, 189, 25, 206, 56, 94, 185, 110, 30, 79, 163, 204, 136, 115, 215, 76, 42, 192, 179, 13, 20, 176, 187, 216, 167, 221, 53, 235, 91, 173, - 106, 137, 87, 121, 234, 183, 42, 176, 168, 251, 98, 177, 2, 171, 65, 224, 241, 197, 186, 15, 185, 174, 90, 217, 246, 86, 228, 156, 32, 86, 196, 64, 160, 102, 41, 1, 130, 84, 136, 69, 211, 5, 146, 30, 62, 77, 0, 128, 121, 247, 174, 230, 230, 61, 242, 126, 101, 222, 171, 97, 119, 95, 130, 10, 187, 32, 90, 204, 65, 128, 163, 17, 36, 226, 68, 105, 88, 112, 63, 53, 234, 81, 213, 204, 40, 136, 78, 69, 84, 151, 16, 43, 236, 205, 200, 195, 224, 213, 81, 94, - 33, 100, 248, 183, 232, 101, 222, 160, 149, 185, 122, 36, 149, 249, 151, 45, 10, 157, 185, 140, 40, 61, 148, 182, 239, 242, 56, 110, 173, 55, 150, 216, 244, 68, 180, 3, 97, 183, 181, 252, 50, 222, 103, 112, 217, 69, 114, 77, 255, 187, 69, 33, 105, 222, 99, 235, 102, 178, 112, 1, 138, 237, 127, 192, 72, 214, 254, 25, 226, 193, 40, 6, 75, 27, 129, 173, 152, 109, 135, 181, 91, 164, 28, 109, 90, 159, 85, 241, 221, 135, 27, 159, 136, 242, 6, 10, 128, 134, 171, 85, - 206, 112, 213, 193, 131, 221, 7, 145, 18, 187, 15, 68, 133, 57, 132, 51, 149, 192, 77, 113, 42, 188, 93, 178, 60, 195, 137, 166, 64, 112, 172, 91, 111, 155, 47, 63, 50, 63, 32, 149, 2, 238, 12, 194, 254, 87, 249, 228, 244, 180, 45, 93, 130, 183, 114, 57, 159, 253, 160, 143, 45, 230, 15, 34, 55, 4, 82, 237, 90, 157, 148, 27, 8, 4, 25, 225, 22, 227, 186, 129, 48, 29, 206, 23, 24, 73, 171, 112, 17, 140, 75, 226, 163, 202, 75, 173, 232, 111, 204, 39, - 139, 217, 13, 187, 249, 70, 79, 37, 214, 41, 146, 24, 15, 207, 230, 0, 160, 88, 123, 58, 98, 85, 120, 224, 33, 123, 86, 241, 166, 67, 84, 216, 189, 53, 230, 33, 41, 79, 191, 116, 230, 22, 32, 163, 172, 138, 181, 161, 156, 74, 206, 100, 223, 149, 184, 54, 198, 175, 114, 72, 0, 26, 242, 84, 58, 67, 158, 74, 206, 164, 72, 9, 221, 19, 21, 30, 63, 193, 238, 64, 204, 74, 238, 40, 8, 68, 187, 189, 134, 29, 237, 100, 27, 138, 69, 91, 32, 48, 45, 176, - 249, 89, 86, 132, 22, 208, 220, 245, 180, 217, 83, 149, 184, 190, 181, 2, 87, 180, 120, 181, 174, 168, 136, 114, 168, 127, 13, 168, 6, 21, 174, 80, 88, 90, 120, 132, 216, 41, 236, 157, 88, 192, 201, 199, 113, 65, 139, 93, 222, 47, 239, 225, 115, 93, 168, 238, 142, 240, 53, 8, 175, 135, 58, 11, 231, 102, 36, 162, 137, 251, 141, 250, 76, 216, 147, 206, 126, 82, 122, 3, 224, 233, 53, 228, 105, 211, 227, 62, 143, 216, 26, 130, 159, 160, 9, 250, 100, 116, 36, 208, - 234, 228, 205, 20, 127, 62, 236, 121, 108, 246, 156, 249, 133, 225, 92, 239, 140, 156, 166, 220, 36, 167, 76, 118, 91, 173, 237, 62, 249, 81, 15, 155, 6, 209, 235, 99, 138, 191, 163, 66, 241, 205, 238, 142, 197, 56, 35, 39, 254, 33, 194, 55, 46, 199, 213, 45, 151, 120, 9, 120, 122, 161, 191, 0, 254, 199, 147, 236, 232, 118, 202, 239, 28, 139, 92, 26, 50, 182, 33, 5, 237, 162, 152, 4, 64, 139, 164, 4, 200, 65, 225, 21, 221, 237, 164, 196, 89, 96, 162, 194, - 131, 142, 173, 145, 31, 181, 24, 98, 20, 112, 61, 180, 121, 50, 96, 247, 176, 134, 175, 243, 222, 29, 240, 23, 157, 176, 10, 78, 219, 178, 154, 76, 36, 71, 87, 120, 237, 180, 147, 28, 94, 225, 237, 219, 128, 27, 75, 223, 211, 62, 57, 29, 195, 162, 115, 6, 206, 33, 86, 42, 75, 187, 49, 118, 194, 104, 236, 175, 197, 42, 148, 210, 56, 253, 59, 38, 141, 207, 55, 113, 105, 152, 69, 232, 195, 184, 52, 36, 0, 109, 105, 108, 146, 210, 80, 120, 32, 13, 145, 18, - 210, 32, 42, 60, 84, 122, 137, 252, 184, 199, 77, 26, 35, 67, 74, 26, 201, 82, 26, 248, 81, 73, 67, 36, 133, 52, 146, 237, 241, 58, 22, 153, 128, 189, 116, 148, 48, 168, 168, 253, 241, 132, 193, 250, 225, 143, 129, 106, 32, 13, 2, 249, 25, 67, 55, 9, 47, 40, 127, 77, 172, 240, 138, 49, 223, 80, 41, 131, 17, 9, 241, 224, 146, 19, 14, 203, 15, 230, 196, 114, 47, 195, 25, 231, 224, 112, 82, 70, 231, 213, 203, 39, 133, 140, 146, 101, 232, 84, 185, 192, - 199, 10, 250, 208, 253, 167, 97, 125, 126, 117, 159, 234, 58, 54, 109, 2, 187, 39, 52, 118, 93, 45, 236, 205, 2, 23, 17, 185, 31, 179, 99, 88, 180, 197, 54, 164, 151, 61, 67, 91, 190, 72, 226, 30, 225, 69, 186, 85, 201, 97, 4, 142, 235, 39, 99, 172, 56, 28, 124, 109, 191, 79, 13, 190, 46, 90, 138, 153, 230, 88, 102, 222, 194, 236, 37, 202, 194, 166, 72, 224, 22, 94, 250, 18, 110, 97, 75, 28, 73, 41, 60, 240, 0, 75, 148, 133, 117, 72, 42, 173, - 186, 155, 18, 225, 219, 41, 47, 194, 181, 223, 225, 54, 106, 251, 204, 242, 137, 232, 3, 182, 19, 220, 200, 121, 92, 183, 4, 253, 50, 231, 81, 2, 144, 43, 221, 232, 184, 210, 141, 156, 71, 145, 18, 60, 18, 149, 78, 87, 30, 41, 207, 211, 77, 231, 49, 182, 151, 187, 11, 37, 120, 106, 49, 58, 94, 237, 46, 65, 24, 144, 227, 175, 103, 122, 16, 113, 55, 34, 178, 75, 106, 28, 84, 182, 129, 15, 97, 235, 223, 88, 133, 160, 233, 252, 78, 196, 223, 238, 21, 65, - 245, 223, 1, 87, 73, 0, 236, 46, 154, 179, 139, 238, 54, 38, 182, 187, 230, 7, 9, 219, 119, 131, 123, 7, 254, 8, 22, 251, 216, 210, 174, 215, 102, 7, 33, 228, 93, 75, 125, 110, 107, 179, 172, 34, 201, 8, 119, 213, 82, 159, 182, 46, 139, 241, 117, 67, 70, 65, 121, 244, 20, 156, 0, 85, 212, 62, 9, 65, 251, 143, 229, 82, 197, 10, 17, 166, 224, 132, 148, 25, 141, 4, 115, 148, 210, 114, 62, 71, 9, 222, 171, 154, 73, 11, 236, 248, 75, 80, 97, 29, - 68, 72, 78, 127, 219, 126, 233, 224, 199, 25, 250, 237, 22, 202, 216, 91, 238, 220, 110, 145, 68, 178, 221, 237, 92, 138, 229, 91, 160, 27, 240, 167, 212, 65, 132, 201, 27, 61, 169, 30, 79, 67, 103, 178, 93, 155, 159, 59, 62, 224, 220, 98, 62, 93, 110, 27, 32, 159, 88, 57, 155, 82, 151, 155, 132, 72, 107, 0, 201, 143, 143, 150, 159, 150, 240, 206, 162, 172, 123, 8, 168, 18, 172, 180, 177, 216, 167, 173, 196, 10, 54, 220, 212, 55, 6, 17, 126, 181, 152, 79, - 123, 105, 73, 211, 26, 147, 38, 87, 53, 203, 199, 180, 167, 212, 65, 236, 206, 195, 235, 185, 180, 147, 134, 42, 105, 207, 221, 160, 232, 168, 117, 89, 187, 62, 5, 126, 217, 137, 6, 146, 60, 14, 200, 52, 199, 162, 98, 71, 178, 111, 108, 16, 93, 196, 105, 181, 121, 183, 200, 71, 86, 20, 164, 136, 135, 239, 44, 226, 115, 231, 144, 241, 46, 242, 69, 181, 196, 233, 87, 224, 43, 108, 67, 62, 5, 172, 230, 206, 97, 119, 224, 30, 112, 25, 20, 162, 92, 125, 5, 17, - 167, 168, 68, 116, 35, 240, 19, 108, 146, 232, 200, 25, 182, 184, 143, 69, 112, 16, 101, 232, 86, 122, 171, 230, 79, 241, 113, 163, 39, 199, 244, 81, 155, 125, 75, 114, 221, 138, 110, 114, 134, 203, 240, 77, 94, 114, 37, 148, 232, 201, 49, 15, 22, 185, 90, 238, 255, 195, 41, 6, 99, 229, 111, 99, 166, 199, 15, 149, 241, 121, 33, 1, 236, 112, 3, 192, 38, 73, 9, 168, 130, 194, 131, 121, 161, 72, 65, 187, 170, 145, 84, 216, 156, 248, 204, 235, 137, 206, 187, 105, - 15, 255, 8, 139, 154, 182, 17, 239, 47, 45, 222, 159, 228, 247, 120, 214, 204, 149, 24, 108, 66, 108, 231, 249, 236, 188, 148, 80, 86, 34, 204, 40, 247, 39, 64, 162, 108, 12, 222, 171, 34, 224, 122, 94, 107, 10, 85, 243, 51, 124, 242, 139, 68, 67, 64, 124, 110, 122, 59, 81, 130, 103, 137, 151, 221, 46, 1, 90, 180, 34, 175, 74, 135, 82, 94, 238, 166, 8, 176, 9, 103, 219, 83, 242, 99, 179, 94, 52, 188, 16, 122, 166, 76, 239, 56, 244, 24, 131, 5, 247, - 80, 199, 177, 184, 76, 105, 129, 79, 80, 139, 91, 141, 112, 127, 43, 208, 106, 183, 245, 76, 148, 205, 1, 59, 1, 239, 71, 5, 14, 194, 123, 189, 185, 125, 96, 34, 108, 255, 205, 50, 27, 156, 162, 178, 205, 213, 89, 233, 86, 224, 0, 172, 4, 91, 129, 131, 250, 190, 134, 113, 143, 90, 9, 62, 101, 168, 66, 121, 180, 148, 15, 46, 128, 57, 209, 247, 131, 81, 53, 58, 29, 91, 163, 126, 90, 141, 158, 22, 53, 122, 158, 17, 215, 158, 215, 58, 109, 215, 229, 218, - 148, 186, 102, 248, 85, 155, 123, 117, 74, 237, 17, 250, 213, 35, 165, 182, 131, 126, 93, 149, 82, 219, 73, 191, 232, 121, 214, 67, 148, 72, 193, 68, 61, 81, 72, 67, 105, 52, 82, 206, 149, 152, 35, 232, 92, 129, 137, 99, 148, 72, 150, 15, 251, 58, 76, 7, 78, 216, 194, 232, 111, 11, 163, 143, 185, 44, 43, 203, 22, 85, 166, 133, 15, 134, 103, 88, 248, 212, 185, 45, 184, 70, 18, 220, 17, 16, 156, 21, 56, 70, 103, 220, 155, 105, 158, 248, 222, 61, 114, 101, - 240, 4, 84, 242, 217, 117, 208, 223, 159, 4, 195, 106, 91, 41, 107, 203, 231, 224, 5, 39, 145, 221, 225, 205, 182, 246, 58, 69, 170, 118, 120, 243, 245, 80, 107, 76, 89, 19, 155, 51, 52, 205, 225, 194, 61, 245, 155, 175, 15, 81, 186, 26, 8, 219, 42, 129, 147, 23, 29, 153, 106, 193, 18, 79, 246, 42, 41, 149, 25, 60, 106, 76, 247, 31, 225, 178, 41, 182, 129, 243, 255, 164, 43, 130, 4, 196, 166, 231, 41, 117, 199, 29, 6, 68, 135, 237, 97, 29, 246, 235, - 165, 74, 143, 108, 198, 126, 166, 230, 60, 144, 174, 49, 26, 87, 187, 140, 220, 123, 173, 243, 9, 231, 126, 218, 205, 185, 101, 132, 3, 173, 87, 96, 23, 152, 53, 47, 106, 138, 223, 54, 76, 243, 111, 230, 225, 181, 95, 172, 133, 16, 212, 70, 235, 26, 122, 22, 244, 48, 132, 133, 49, 199, 37, 217, 36, 168, 61, 19, 9, 109, 49, 160, 213, 109, 68, 105, 97, 69, 42, 230, 70, 45, 6, 136, 49, 136, 221, 163, 139, 224, 254, 110, 59, 243, 15, 32, 238, 196, 185, 81, - 75, 2, 246, 56, 106, 205, 165, 134, 5, 157, 131, 169, 45, 108, 94, 171, 208, 249, 50, 65, 244, 244, 89, 138, 175, 21, 225, 63, 159, 19, 187, 76, 128, 241, 188, 208, 223, 150, 23, 116, 20, 154, 99, 218, 67, 198, 91, 37, 106, 236, 244, 52, 205, 26, 231, 68, 77, 235, 21, 16, 109, 199, 148, 200, 190, 90, 225, 194, 42, 47, 225, 77, 115, 193, 131, 17, 84, 193, 26, 110, 34, 47, 14, 86, 38, 178, 21, 22, 244, 37, 40, 244, 244, 17, 73, 139, 173, 21, 180, 13, - 165, 161, 129, 78, 230, 125, 70, 230, 129, 53, 206, 107, 247, 18, 95, 11, 60, 19, 113, 27, 63, 189, 134, 101, 191, 49, 59, 106, 157, 64, 61, 222, 80, 14, 155, 173, 171, 98, 100, 68, 24, 90, 200, 196, 85, 92, 70, 171, 28, 25, 173, 210, 100, 68, 120, 229, 46, 120, 32, 163, 126, 37, 188, 114, 127, 190, 83, 85, 110, 73, 137, 79, 129, 138, 45, 87, 162, 85, 17, 43, 35, 157, 204, 87, 140, 204, 205, 37, 108, 171, 149, 240, 181, 199, 209, 218, 221, 100, 84, 137, - 101, 111, 157, 21, 53, 239, 119, 194, 195, 105, 230, 116, 83, 113, 180, 168, 8, 81, 139, 110, 46, 129, 80, 84, 148, 0, 81, 41, 92, 16, 21, 225, 237, 119, 193, 3, 81, 37, 21, 243, 58, 238, 189, 67, 213, 49, 31, 22, 246, 37, 168, 48, 39, 162, 117, 48, 86, 84, 58, 153, 239, 24, 25, 79, 49, 51, 39, 194, 175, 143, 107, 78, 178, 161, 23, 98, 217, 243, 10, 99, 38, 225, 159, 62, 161, 55, 244, 127, 215, 26, 250, 15, 183, 139, 241, 255, 106, 133, 206, 195, - 201, 184, 204, 176, 206, 35, 104, 66, 97, 204, 132, 187, 183, 40, 41, 78, 196, 249, 70, 196, 27, 246, 4, 159, 18, 31, 157, 25, 53, 225, 86, 0, 168, 33, 74, 128, 134, 20, 30, 76, 137, 69, 74, 198, 255, 156, 25, 53, 53, 103, 171, 203, 148, 167, 133, 143, 113, 223, 127, 181, 70, 145, 36, 106, 210, 220, 39, 150, 62, 100, 191, 223, 172, 174, 39, 150, 32, 113, 219, 21, 205, 138, 55, 177, 148, 2, 121, 21, 225, 90, 10, 245, 137, 101, 42, 221, 134, 20, 158, 244, - 208, 32, 15, 223, 88, 123, 144, 161, 164, 95, 66, 71, 4, 87, 92, 168, 207, 42, 167, 22, 58, 195, 118, 248, 9, 98, 197, 79, 185, 94, 245, 13, 44, 28, 63, 142, 243, 90, 174, 92, 255, 184, 10, 229, 176, 210, 81, 99, 65, 200, 184, 190, 208, 167, 109, 186, 202, 92, 186, 216, 178, 82, 234, 80, 33, 193, 90, 186, 72, 9, 29, 18, 9, 151, 77, 87, 202, 136, 179, 233, 234, 104, 111, 140, 216, 104, 251, 170, 135, 187, 246, 242, 145, 235, 154, 153, 62, 143, 139, 66, - 36, 208, 245, 8, 180, 97, 102, 60, 197, 57, 231, 191, 96, 21, 223, 120, 116, 38, 87, 92, 252, 211, 100, 3, 5, 107, 19, 226, 176, 86, 131, 212, 114, 220, 89, 115, 206, 255, 33, 80, 178, 198, 90, 200, 152, 113, 27, 145, 30, 95, 1, 227, 222, 100, 141, 161, 200, 195, 40, 62, 250, 40, 109, 37, 242, 166, 95, 125, 148, 134, 17, 121, 246, 114, 245, 81, 42, 49, 114, 100, 139, 162, 153, 173, 87, 50, 182, 14, 17, 216, 115, 48, 22, 204, 224, 170, 138, 124, 235, 245, - 56, 31, 229, 172, 62, 178, 141, 125, 148, 243, 247, 200, 192, 110, 234, 163, 156, 163, 71, 6, 36, 168, 143, 114, 194, 29, 201, 245, 168, 143, 114, 138, 29, 249, 148, 209, 148, 83, 230, 200, 189, 73, 234, 227, 34, 23, 201, 202, 131, 218, 183, 32, 235, 175, 60, 198, 167, 190, 208, 79, 38, 120, 88, 84, 11, 227, 171, 34, 52, 98, 91, 214, 67, 182, 130, 92, 16, 158, 207, 108, 195, 222, 44, 24, 38, 70, 94, 169, 86, 217, 218, 89, 34, 122, 152, 209, 158, 220, 192, 237, - 9, 131, 134, 180, 4, 198, 38, 187, 198, 185, 123, 83, 182, 212, 227, 139, 232, 105, 3, 61, 226, 201, 176, 62, 3, 213, 58, 237, 204, 42, 69, 62, 206, 243, 92, 178, 98, 19, 97, 211, 195, 248, 248, 55, 81, 211, 223, 216, 186, 93, 227, 212, 109, 58, 50, 79, 40, 123, 46, 133, 82, 228, 160, 12, 96, 40, 218, 123, 208, 7, 168, 219, 194, 192, 24, 143, 137, 250, 18, 24, 155, 153, 5, 143, 203, 234, 222, 157, 35, 171, 59, 61, 71, 85, 119, 121, 165, 162, 94, 239, - 94, 93, 57, 86, 152, 9, 91, 21, 198, 151, 211, 163, 230, 200, 160, 151, 76, 91, 47, 61, 209, 156, 41, 91, 155, 236, 182, 91, 5, 248, 244, 152, 124, 62, 211, 102, 119, 94, 25, 177, 75, 208, 60, 30, 253, 185, 139, 146, 223, 96, 182, 228, 119, 103, 182, 226, 183, 169, 66, 149, 210, 170, 49, 129, 17, 75, 170, 55, 171, 236, 72, 23, 76, 124, 97, 112, 38, 58, 52, 153, 85, 19, 15, 175, 185, 242, 112, 31, 227, 161, 83, 23, 4, 240, 112, 21, 227, 129, 77, 197, - 64, 199, 221, 52, 29, 175, 95, 38, 117, 124, 63, 67, 209, 246, 105, 93, 216, 190, 85, 99, 155, 77, 233, 148, 170, 223, 119, 101, 219, 122, 82, 21, 146, 222, 69, 33, 127, 90, 199, 11, 201, 116, 43, 228, 75, 215, 66, 110, 98, 133, 244, 225, 195, 28, 53, 160, 146, 241, 126, 174, 129, 245, 126, 99, 251, 163, 81, 115, 180, 80, 224, 32, 112, 48, 183, 12, 8, 81, 174, 246, 252, 244, 196, 24, 195, 60, 6, 171, 169, 198, 248, 71, 163, 167, 96, 129, 14, 113, 168, 2, - 206, 135, 4, 129, 28, 193, 140, 112, 231, 75, 54, 235, 98, 36, 215, 237, 209, 168, 41, 86, 40, 208, 20, 246, 220, 250, 88, 225, 173, 225, 92, 239, 244, 69, 139, 150, 134, 115, 253, 243, 231, 252, 102, 73, 56, 55, 121, 250, 146, 149, 3, 10, 195, 185, 169, 179, 86, 53, 229, 246, 176, 225, 94, 193, 142, 200, 232, 61, 128, 124, 199, 200, 32, 201, 146, 40, 178, 185, 87, 233, 57, 120, 148, 89, 202, 243, 166, 1, 82, 158, 119, 12, 80, 242, 252, 40, 4, 124, 19, 42, - 159, 126, 81, 33, 210, 228, 190, 40, 227, 69, 204, 230, 69, 36, 116, 89, 196, 82, 86, 196, 162, 152, 34, 236, 106, 67, 37, 202, 180, 18, 86, 184, 25, 196, 36, 87, 234, 215, 48, 234, 107, 19, 92, 59, 24, 233, 130, 189, 176, 185, 98, 152, 83, 99, 166, 81, 145, 254, 36, 201, 135, 132, 36, 9, 132, 205, 142, 202, 148, 85, 246, 151, 76, 156, 237, 175, 152, 168, 216, 4, 76, 16, 154, 182, 73, 234, 189, 133, 40, 95, 44, 227, 148, 217, 76, 104, 237, 185, 4, 73, - 250, 103, 183, 184, 145, 190, 157, 145, 214, 38, 66, 87, 11, 210, 187, 52, 210, 251, 221, 152, 118, 167, 252, 169, 165, 40, 179, 233, 141, 212, 249, 104, 141, 110, 189, 27, 221, 158, 174, 116, 13, 70, 247, 8, 215, 72, 236, 226, 198, 18, 88, 43, 54, 190, 159, 18, 53, 105, 137, 120, 132, 34, 40, 167, 197, 205, 26, 86, 222, 44, 203, 174, 186, 89, 149, 221, 29, 203, 38, 180, 86, 189, 78, 118, 74, 88, 59, 101, 179, 217, 70, 164, 162, 140, 151, 199, 230, 26, 204, 95, - 252, 193, 181, 192, 173, 27, 21, 197, 206, 88, 33, 206, 100, 5, 122, 248, 30, 218, 27, 55, 147, 246, 222, 45, 83, 0, 108, 35, 143, 59, 108, 90, 98, 159, 183, 80, 118, 230, 197, 140, 102, 170, 27, 205, 223, 50, 154, 233, 110, 0, 254, 160, 2, 200, 188, 84, 161, 163, 156, 66, 253, 172, 208, 62, 110, 52, 15, 176, 66, 179, 187, 197, 106, 125, 242, 132, 210, 246, 84, 175, 115, 80, 109, 197, 66, 208, 252, 143, 15, 97, 247, 171, 177, 32, 156, 215, 251, 125, 137, 238, - 185, 5, 20, 35, 140, 64, 89, 188, 72, 60, 202, 254, 161, 128, 250, 120, 129, 34, 55, 66, 219, 61, 165, 190, 242, 19, 1, 87, 203, 224, 198, 233, 53, 135, 11, 191, 161, 160, 255, 60, 30, 116, 243, 90, 244, 96, 119, 5, 131, 103, 225, 29, 9, 142, 66, 130, 7, 189, 246, 79, 17, 21, 252, 45, 248, 173, 30, 167, 119, 30, 243, 254, 155, 40, 254, 78, 70, 142, 199, 132, 20, 112, 84, 186, 13, 55, 3, 165, 77, 112, 179, 185, 180, 59, 250, 146, 233, 41, 249, 180, - 223, 70, 166, 75, 192, 44, 20, 36, 51, 221, 239, 251, 74, 211, 77, 232, 199, 218, 255, 6, 85, 200, 10, 93, 102, 54, 221, 180, 249, 138, 85, 22, 151, 177, 180, 17, 148, 232, 242, 128, 253, 223, 135, 16, 63, 3, 124, 114, 130, 81, 33, 254, 163, 109, 31, 130, 43, 109, 135, 35, 238, 133, 225, 192, 233, 68, 248, 247, 11, 216, 28, 129, 193, 156, 140, 186, 22, 14, 180, 208, 31, 92, 216, 142, 124, 50, 15, 130, 186, 181, 90, 70, 165, 253, 35, 156, 139, 166, 97, 59, - 68, 250, 227, 167, 63, 169, 160, 5, 113, 103, 23, 244, 88, 155, 32, 2, 205, 117, 115, 182, 119, 106, 129, 76, 83, 78, 125, 240, 187, 148, 114, 220, 19, 43, 110, 78, 233, 53, 220, 230, 3, 255, 53, 87, 83, 228, 193, 203, 236, 28, 88, 239, 238, 59, 15, 163, 37, 95, 30, 249, 102, 174, 61, 163, 27, 236, 93, 118, 42, 100, 204, 233, 163, 214, 195, 175, 180, 243, 173, 55, 43, 17, 202, 236, 190, 236, 222, 80, 112, 17, 157, 142, 196, 220, 116, 252, 190, 98, 104, 56, - 63, 157, 143, 184, 173, 238, 192, 200, 56, 59, 19, 3, 63, 149, 54, 130, 28, 112, 249, 26, 144, 94, 176, 75, 162, 79, 57, 245, 248, 145, 192, 183, 219, 159, 115, 234, 195, 221, 129, 64, 219, 177, 148, 94, 16, 164, 217, 227, 177, 229, 105, 180, 247, 49, 167, 158, 37, 145, 154, 69, 157, 102, 241, 121, 51, 108, 189, 58, 212, 6, 183, 146, 100, 43, 134, 37, 136, 144, 247, 45, 143, 71, 88, 76, 94, 6, 144, 52, 108, 152, 17, 203, 186, 135, 243, 240, 198, 117, 66, 137, - 183, 111, 137, 223, 154, 122, 214, 42, 234, 180, 138, 207, 31, 125, 55, 165, 87, 46, 209, 79, 55, 167, 118, 74, 250, 231, 173, 87, 79, 205, 177, 73, 95, 25, 60, 186, 44, 203, 202, 243, 195, 209, 30, 43, 9, 168, 253, 211, 254, 28, 78, 66, 201, 231, 81, 240, 77, 132, 12, 231, 165, 99, 34, 47, 205, 154, 218, 105, 21, 217, 116, 11, 153, 188, 173, 73, 233, 193, 227, 43, 223, 142, 12, 130, 216, 13, 117, 133, 21, 178, 188, 152, 250, 44, 180, 73, 149, 150, 248, 47, - 218, 13, 243, 241, 158, 118, 185, 161, 180, 193, 230, 36, 127, 104, 248, 250, 12, 198, 113, 97, 197, 65, 136, 229, 20, 249, 2, 130, 91, 2, 111, 203, 62, 180, 214, 103, 216, 19, 57, 51, 47, 35, 30, 78, 74, 47, 152, 247, 121, 196, 159, 2, 212, 8, 48, 225, 143, 128, 38, 241, 181, 80, 100, 89, 200, 27, 2, 109, 82, 190, 173, 43, 171, 200, 111, 27, 140, 215, 42, 78, 142, 252, 18, 212, 158, 109, 94, 48, 23, 121, 45, 59, 195, 254, 10, 164, 57, 124, 36, 83, - 210, 131, 53, 161, 113, 34, 31, 218, 131, 209, 158, 106, 21, 37, 75, 179, 131, 24, 144, 37, 94, 144, 232, 59, 128, 128, 178, 157, 9, 191, 242, 240, 227, 195, 240, 51, 31, 127, 62, 128, 63, 253, 214, 100, 56, 181, 8, 247, 139, 35, 83, 241, 75, 170, 53, 57, 77, 126, 25, 133, 95, 210, 173, 201, 25, 166, 109, 255, 5, 201, 70, 99, 170, 109, 83, 103, 64, 222, 142, 126, 221, 236, 231, 194, 44, 91, 201, 121, 126, 107, 82, 114, 223, 195, 119, 157, 91, 58, 34, 33, - 207, 27, 60, 30, 26, 155, 81, 52, 213, 182, 170, 60, 108, 110, 230, 36, 92, 130, 132, 137, 50, 217, 87, 165, 92, 137, 4, 230, 174, 152, 237, 131, 231, 103, 18, 243, 146, 239, 10, 155, 121, 201, 143, 223, 226, 208, 12, 77, 92, 159, 17, 242, 118, 55, 243, 192, 216, 204, 102, 165, 8, 176, 7, 111, 169, 173, 171, 182, 103, 250, 134, 115, 142, 39, 148, 164, 10, 75, 106, 251, 72, 179, 247, 40, 123, 28, 75, 100, 109, 109, 251, 34, 237, 184, 29, 228, 151, 65, 38, 27, - 90, 49, 116, 62, 9, 49, 8, 112, 206, 175, 134, 206, 110, 102, 158, 87, 218, 164, 162, 223, 96, 126, 142, 54, 160, 118, 248, 75, 207, 13, 203, 206, 30, 180, 236, 215, 240, 92, 105, 122, 185, 221, 61, 219, 127, 83, 203, 3, 223, 194, 95, 127, 121, 224, 187, 16, 246, 216, 169, 33, 244, 47, 201, 229, 5, 223, 55, 5, 58, 6, 53, 5, 190, 206, 110, 10, 252, 195, 254, 255, 155, 97, 214, 48, 113, 188, 243, 189, 27, 196, 250, 159, 241, 247, 66, 233, 76, 91, 11, 161, - 93, 211, 166, 120, 97, 133, 115, 12, 207, 174, 4, 149, 110, 165, 6, 143, 23, 249, 229, 201, 180, 200, 20, 91, 113, 118, 77, 103, 67, 52, 255, 85, 201, 214, 230, 121, 5, 62, 15, 107, 79, 41, 181, 221, 223, 134, 46, 194, 108, 40, 15, 180, 52, 252, 53, 221, 60, 50, 54, 167, 57, 225, 120, 67, 103, 175, 132, 163, 55, 214, 93, 215, 224, 205, 57, 108, 92, 184, 88, 20, 201, 95, 91, 220, 226, 41, 250, 192, 178, 102, 217, 248, 38, 82, 177, 27, 244, 13, 150, 1, - 105, 48, 210, 251, 188, 230, 102, 252, 13, 167, 136, 224, 63, 201, 65, 200, 88, 147, 64, 26, 254, 114, 166, 207, 211, 246, 126, 252, 246, 179, 227, 199, 139, 23, 115, 142, 219, 204, 118, 179, 82, 143, 154, 205, 212, 159, 56, 237, 33, 157, 108, 45, 178, 202, 134, 210, 35, 177, 218, 24, 215, 90, 217, 57, 199, 97, 49, 241, 48, 58, 211, 203, 154, 204, 162, 14, 19, 94, 127, 233, 176, 10, 98, 251, 39, 214, 20, 35, 79, 192, 88, 197, 110, 62, 73, 145, 197, 208, 34, 243, - 188, 145, 57, 240, 55, 223, 27, 41, 197, 191, 126, 115, 114, 114, 100, 57, 254, 76, 53, 39, 167, 69, 230, 225, 207, 116, 115, 114, 134, 211, 108, 121, 255, 84, 144, 83, 15, 26, 121, 27, 26, 230, 4, 243, 107, 225, 224, 138, 55, 149, 182, 207, 183, 43, 122, 254, 155, 125, 161, 226, 253, 230, 215, 223, 236, 179, 140, 19, 19, 208, 7, 4, 211, 160, 101, 149, 253, 183, 93, 77, 51, 120, 236, 2, 180, 50, 46, 31, 171, 26, 190, 89, 33, 248, 215, 56, 156, 97, 86, 123, - 108, 240, 239, 134, 165, 39, 164, 148, 189, 140, 109, 255, 64, 226, 176, 12, 216, 94, 31, 150, 1, 59, 31, 207, 225, 183, 67, 86, 65, 125, 56, 216, 114, 129, 174, 74, 153, 193, 122, 251, 151, 89, 253, 127, 236, 61, 121, 124, 19, 101, 218, 147, 222, 39, 41, 199, 114, 8, 44, 163, 82, 44, 182, 64, 89, 149, 181, 45, 85, 122, 164, 165, 216, 66, 33, 45, 40, 226, 134, 73, 50, 77, 67, 147, 76, 200, 76, 122, 32, 46, 98, 200, 74, 28, 195, 226, 66, 93, 214, 85, - 4, 129, 149, 117, 21, 185, 202, 93, 168, 149, 69, 112, 61, 56, 202, 165, 28, 138, 117, 183, 93, 60, 17, 57, 68, 201, 247, 60, 239, 204, 228, 40, 41, 238, 247, 91, 190, 255, 62, 134, 166, 239, 188, 207, 241, 62, 247, 123, 100, 146, 238, 133, 215, 197, 34, 97, 32, 122, 17, 40, 230, 71, 189, 245, 105, 164, 88, 17, 23, 37, 70, 197, 69, 18, 172, 222, 4, 43, 152, 194, 83, 217, 34, 209, 224, 251, 217, 249, 81, 226, 220, 184, 168, 172, 39, 246, 139, 247, 198, 205, - 187, 109, 110, 175, 44, 231, 94, 190, 183, 28, 72, 146, 188, 30, 231, 94, 15, 128, 221, 72, 225, 35, 34, 72, 99, 229, 196, 57, 22, 160, 253, 101, 125, 166, 64, 113, 240, 144, 166, 218, 61, 0, 61, 224, 173, 198, 87, 119, 33, 14, 228, 221, 69, 100, 216, 79, 228, 109, 198, 27, 98, 206, 209, 45, 63, 162, 229, 60, 223, 138, 205, 8, 2, 27, 18, 219, 137, 141, 248, 234, 106, 25, 228, 113, 31, 68, 214, 142, 254, 151, 247, 97, 76, 169, 23, 224, 218, 64, 116, 91, - 0, 26, 153, 15, 80, 108, 136, 249, 196, 76, 207, 168, 16, 34, 16, 234, 122, 92, 1, 184, 113, 33, 32, 25, 107, 61, 81, 125, 243, 117, 169, 222, 137, 141, 132, 169, 55, 197, 119, 131, 189, 214, 19, 123, 109, 38, 178, 6, 136, 60, 132, 161, 68, 230, 145, 134, 80, 172, 246, 36, 90, 173, 223, 220, 164, 172, 166, 185, 208, 205, 39, 35, 127, 15, 105, 123, 0, 70, 164, 247, 17, 65, 164, 225, 178, 226, 234, 230, 75, 202, 129, 78, 74, 189, 145, 58, 70, 31, 24, 13, - 209, 64, 195, 124, 64, 210, 231, 200, 39, 238, 125, 66, 130, 24, 225, 106, 133, 186, 209, 220, 86, 156, 231, 186, 26, 237, 252, 92, 66, 245, 142, 109, 198, 202, 230, 105, 254, 132, 120, 156, 60, 175, 254, 234, 37, 172, 9, 206, 18, 209, 75, 184, 43, 213, 230, 139, 219, 149, 106, 115, 202, 168, 84, 27, 135, 62, 90, 30, 83, 246, 25, 9, 87, 55, 123, 29, 63, 105, 135, 33, 45, 85, 153, 251, 126, 36, 85, 198, 154, 203, 24, 13, 38, 97, 172, 76, 145, 47, 51, 198, - 239, 126, 232, 202, 120, 0, 48, 238, 248, 224, 50, 204, 226, 43, 100, 49, 102, 247, 239, 252, 37, 252, 238, 232, 188, 70, 254, 184, 33, 113, 110, 199, 139, 63, 16, 198, 71, 59, 142, 224, 103, 40, 9, 98, 78, 94, 28, 120, 16, 159, 191, 89, 114, 194, 136, 159, 9, 252, 70, 14, 244, 119, 220, 23, 149, 86, 126, 127, 178, 176, 203, 151, 22, 125, 249, 113, 202, 250, 142, 10, 94, 85, 69, 160, 28, 43, 24, 144, 136, 176, 192, 192, 184, 22, 161, 152, 248, 82, 126, 127, - 149, 48, 94, 116, 151, 66, 123, 156, 135, 252, 26, 175, 94, 144, 140, 112, 247, 120, 148, 130, 196, 147, 122, 65, 44, 57, 188, 190, 23, 52, 148, 164, 35, 143, 93, 40, 22, 29, 7, 221, 157, 17, 168, 92, 51, 210, 184, 125, 206, 54, 177, 105, 40, 182, 46, 57, 223, 21, 53, 75, 241, 137, 175, 177, 24, 139, 222, 52, 236, 60, 160, 94, 48, 146, 68, 230, 80, 146, 111, 139, 69, 119, 26, 105, 44, 21, 221, 25, 164, 177, 76, 116, 103, 146, 198, 139, 162, 251, 94, 210, - 88, 33, 186, 239, 39, 141, 213, 162, 123, 44, 105, 172, 21, 221, 227, 72, 227, 117, 201, 132, 16, 43, 151, 196, 250, 254, 158, 86, 8, 24, 37, 90, 222, 241, 71, 75, 83, 91, 145, 28, 45, 174, 19, 80, 144, 208, 54, 56, 121, 193, 22, 20, 61, 233, 113, 227, 26, 164, 195, 116, 89, 73, 51, 49, 159, 172, 137, 99, 46, 43, 206, 16, 243, 82, 80, 137, 19, 196, 110, 152, 150, 210, 230, 117, 37, 89, 75, 76, 66, 52, 226, 20, 196, 89, 137, 150, 34, 12, 3, 167, - 67, 171, 58, 210, 9, 142, 98, 127, 252, 6, 239, 142, 109, 223, 67, 62, 95, 129, 4, 118, 225, 99, 32, 68, 9, 239, 146, 68, 152, 10, 197, 241, 73, 16, 165, 96, 83, 117, 89, 43, 62, 22, 212, 57, 17, 17, 42, 159, 133, 141, 189, 91, 77, 124, 146, 70, 162, 51, 18, 41, 42, 23, 123, 137, 29, 209, 237, 52, 21, 216, 185, 236, 215, 69, 147, 55, 137, 207, 92, 87, 116, 240, 186, 236, 73, 210, 146, 196, 239, 184, 21, 97, 34, 214, 164, 195, 55, 102, 159, 37, - 223, 250, 182, 146, 148, 135, 66, 165, 190, 120, 72, 72, 136, 238, 114, 146, 250, 21, 88, 113, 72, 234, 247, 38, 197, 192, 35, 245, 187, 73, 166, 19, 168, 88, 249, 100, 86, 227, 12, 148, 117, 209, 43, 184, 146, 118, 207, 36, 8, 40, 125, 207, 70, 163, 20, 113, 105, 82, 196, 69, 70, 42, 1, 145, 163, 217, 172, 118, 63, 71, 76, 146, 65, 198, 193, 80, 136, 212, 236, 234, 93, 9, 179, 8, 233, 209, 236, 245, 144, 78, 177, 114, 127, 86, 35, 134, 197, 188, 94, 106, - 239, 65, 50, 179, 144, 104, 33, 125, 42, 18, 39, 16, 124, 61, 27, 199, 249, 36, 207, 108, 7, 109, 58, 235, 127, 82, 28, 225, 109, 70, 39, 109, 199, 154, 11, 19, 86, 39, 46, 145, 160, 104, 185, 31, 70, 121, 93, 229, 68, 161, 135, 9, 59, 212, 160, 243, 193, 64, 20, 108, 141, 80, 146, 18, 107, 222, 132, 56, 213, 126, 15, 241, 126, 71, 223, 43, 56, 144, 103, 159, 122, 65, 46, 58, 56, 22, 110, 231, 95, 71, 247, 171, 151, 182, 170, 183, 252, 224, 186, 18, - 15, 196, 88, 66, 96, 215, 217, 74, 32, 43, 213, 141, 45, 11, 14, 66, 208, 144, 94, 41, 108, 212, 133, 100, 78, 32, 127, 4, 3, 56, 200, 35, 69, 160, 51, 127, 196, 180, 201, 239, 131, 66, 92, 130, 38, 240, 89, 208, 64, 76, 138, 116, 57, 36, 180, 213, 110, 147, 79, 9, 71, 15, 209, 179, 243, 232, 181, 160, 233, 86, 174, 175, 94, 2, 79, 26, 218, 209, 10, 81, 216, 89, 138, 139, 13, 119, 135, 191, 192, 172, 149, 91, 202, 212, 131, 247, 145, 229, 125, 130, - 190, 155, 28, 221, 233, 105, 60, 133, 90, 103, 94, 196, 8, 195, 166, 168, 34, 223, 197, 252, 29, 146, 156, 146, 102, 94, 178, 94, 255, 14, 185, 183, 249, 185, 39, 249, 148, 214, 235, 164, 111, 165, 234, 252, 96, 31, 129, 207, 151, 123, 34, 40, 87, 51, 222, 71, 171, 23, 188, 129, 82, 111, 241, 226, 29, 73, 107, 41, 65, 33, 185, 243, 251, 11, 239, 138, 110, 50, 140, 55, 137, 72, 137, 180, 98, 233, 194, 56, 8, 127, 207, 126, 85, 139, 199, 251, 197, 117, 41, 9, - 59, 188, 40, 146, 251, 11, 63, 174, 187, 69, 20, 188, 109, 194, 176, 209, 138, 93, 196, 152, 98, 113, 106, 148, 107, 95, 156, 178, 63, 72, 7, 138, 172, 102, 164, 112, 126, 38, 18, 137, 61, 130, 187, 109, 92, 55, 98, 122, 8, 134, 218, 173, 245, 41, 201, 230, 35, 214, 20, 27, 113, 58, 82, 17, 251, 137, 164, 39, 39, 47, 69, 253, 212, 26, 244, 202, 230, 107, 74, 21, 161, 58, 94, 186, 0, 29, 231, 177, 244, 107, 54, 123, 72, 22, 116, 94, 135, 136, 200, 34, - 241, 172, 118, 101, 130, 123, 58, 135, 252, 20, 98, 1, 119, 139, 215, 229, 194, 114, 60, 33, 201, 187, 196, 136, 197, 162, 228, 160, 148, 198, 228, 27, 149, 160, 108, 72, 233, 188, 236, 81, 152, 128, 202, 190, 5, 6, 131, 174, 162, 27, 162, 124, 138, 107, 81, 52, 245, 155, 164, 67, 98, 233, 113, 199, 145, 9, 176, 143, 234, 160, 212, 236, 208, 64, 112, 120, 246, 117, 60, 240, 189, 28, 200, 42, 117, 99, 171, 235, 74, 4, 4, 109, 92, 171, 218, 141, 231, 252, 29, 119, - 124, 143, 42, 35, 118, 142, 74, 237, 30, 129, 93, 106, 236, 106, 36, 93, 249, 81, 176, 240, 81, 41, 129, 52, 26, 198, 111, 247, 135, 193, 106, 217, 249, 174, 150, 161, 30, 247, 138, 235, 138, 20, 210, 74, 249, 42, 241, 176, 115, 90, 241, 124, 25, 15, 108, 237, 139, 118, 158, 10, 206, 134, 175, 72, 136, 145, 108, 32, 198, 118, 75, 134, 39, 10, 121, 241, 53, 107, 124, 138, 250, 233, 222, 104, 77, 45, 88, 51, 100, 127, 237, 109, 39, 20, 68, 225, 198, 21, 74, 224, - 120, 127, 196, 86, 47, 79, 227, 21, 12, 236, 226, 139, 68, 251, 113, 240, 43, 167, 9, 165, 240, 180, 58, 39, 137, 110, 196, 81, 181, 100, 181, 58, 11, 20, 46, 132, 10, 2, 74, 62, 223, 240, 17, 114, 177, 145, 116, 19, 20, 111, 212, 49, 79, 161, 183, 45, 207, 69, 244, 76, 242, 144, 206, 78, 76, 90, 87, 179, 124, 140, 152, 142, 46, 116, 191, 12, 9, 223, 185, 212, 159, 245, 129, 73, 191, 51, 5, 58, 171, 70, 6, 237, 247, 252, 231, 69, 248, 225, 36, 11, - 230, 160, 235, 177, 241, 100, 173, 173, 105, 23, 10, 186, 230, 251, 19, 237, 163, 47, 185, 222, 25, 228, 191, 175, 108, 151, 236, 252, 173, 100, 231, 33, 69, 174, 235, 209, 206, 78, 177, 172, 93, 44, 137, 114, 31, 240, 148, 181, 59, 223, 83, 118, 54, 100, 125, 24, 43, 78, 139, 114, 189, 147, 164, 44, 42, 222, 250, 36, 18, 103, 16, 156, 104, 204, 143, 192, 118, 167, 101, 113, 232, 63, 255, 254, 93, 131, 15, 20, 246, 148, 118, 215, 111, 7, 228, 151, 183, 52, 254, 243, - 3, 124, 216, 41, 83, 172, 143, 234, 248, 14, 50, 65, 181, 15, 110, 123, 30, 247, 100, 122, 234, 163, 92, 45, 113, 62, 252, 88, 33, 190, 41, 150, 165, 73, 114, 30, 147, 89, 81, 210, 63, 157, 206, 216, 96, 49, 234, 172, 76, 13, 171, 51, 178, 22, 166, 129, 133, 27, 206, 232, 180, 176, 58, 179, 205, 44, 152, 25, 139, 121, 14, 235, 208, 25, 24, 139, 133, 15, 198, 231, 140, 58, 129, 117, 88, 117, 85, 78, 155, 1, 1, 5, 69, 26, 93, 145, 86, 87, 200, 26, - 56, 171, 221, 193, 242, 82, 159, 54, 180, 47, 155, 46, 96, 108, 54, 78, 160, 57, 59, 107, 163, 121, 206, 233, 48, 176, 116, 149, 217, 194, 102, 211, 169, 252, 207, 226, 27, 89, 94, 48, 219, 24, 193, 204, 217, 2, 68, 67, 68, 106, 200, 114, 24, 107, 84, 37, 207, 58, 248, 81, 182, 6, 198, 102, 168, 54, 215, 140, 42, 100, 249, 26, 129, 179, 143, 50, 84, 177, 35, 120, 198, 102, 212, 115, 245, 163, 244, 78, 179, 197, 56, 202, 96, 119, 142, 198, 238, 81, 78, 208, - 111, 132, 0, 76, 71, 85, 241, 216, 161, 171, 226, 193, 4, 202, 216, 35, 77, 6, 35, 163, 232, 149, 173, 101, 133, 10, 179, 149, 29, 81, 196, 192, 192, 70, 90, 224, 232, 58, 135, 89, 96, 105, 173, 83, 207, 3, 137, 205, 200, 211, 105, 90, 129, 17, 156, 124, 110, 102, 125, 106, 230, 253, 15, 15, 79, 248, 121, 218, 238, 8, 187, 165, 179, 240, 44, 91, 67, 11, 208, 9, 6, 96, 45, 225, 104, 111, 145, 29, 24, 187, 89, 50, 128, 236, 87, 109, 53, 227, 96, 141, - 101, 78, 129, 173, 167, 168, 34, 45, 45, 221, 211, 133, 140, 192, 208, 164, 151, 54, 56, 88, 217, 53, 68, 220, 219, 233, 41, 5, 146, 84, 245, 1, 252, 32, 244, 10, 8, 56, 90, 227, 112, 208, 168, 0, 34, 214, 103, 228, 217, 237, 185, 169, 198, 140, 34, 136, 40, 100, 148, 139, 33, 17, 150, 182, 216, 92, 251, 31, 209, 222, 34, 91, 216, 29, 230, 90, 57, 26, 40, 42, 149, 215, 89, 56, 211, 72, 161, 94, 160, 234, 40, 186, 60, 79, 171, 213, 20, 210, 16, 136, - 244, 8, 120, 73, 160, 232, 162, 188, 146, 210, 144, 158, 4, 104, 201, 104, 144, 67, 52, 242, 230, 71, 38, 72, 253, 50, 114, 170, 145, 116, 167, 241, 195, 17, 240, 223, 203, 237, 20, 116, 188, 0, 129, 169, 8, 77, 211, 147, 180, 186, 124, 109, 249, 52, 12, 187, 10, 174, 160, 80, 75, 99, 62, 179, 198, 108, 58, 13, 69, 168, 156, 162, 129, 200, 209, 65, 127, 62, 107, 210, 5, 240, 167, 176, 140, 177, 200, 193, 89, 187, 33, 184, 57, 158, 182, 178, 160, 64, 163, 213, - 202, 140, 53, 54, 163, 142, 50, 153, 245, 122, 214, 97, 38, 117, 68, 161, 45, 102, 5, 0, 107, 161, 200, 132, 29, 34, 128, 167, 185, 17, 47, 48, 68, 8, 191, 169, 156, 5, 34, 209, 194, 22, 154, 249, 154, 50, 214, 26, 142, 175, 132, 171, 155, 2, 6, 99, 28, 66, 1, 65, 160, 140, 78, 171, 181, 129, 174, 146, 67, 8, 120, 2, 74, 54, 198, 25, 231, 200, 160, 205, 182, 90, 40, 133, 70, 218, 206, 56, 24, 43, 11, 165, 143, 199, 132, 4, 12, 11, 199, 24, - 33, 250, 138, 96, 192, 91, 228, 59, 61, 111, 15, 231, 63, 179, 77, 203, 90, 49, 109, 210, 82, 141, 195, 179, 101, 173, 18, 36, 160, 193, 194, 241, 164, 63, 88, 201, 174, 144, 96, 115, 201, 64, 204, 89, 137, 93, 1, 9, 78, 78, 170, 180, 16, 154, 55, 248, 249, 102, 184, 65, 156, 245, 102, 155, 81, 46, 1, 52, 20, 3, 32, 156, 236, 100, 157, 108, 1, 82, 179, 35, 105, 214, 225, 176, 113, 116, 46, 132, 60, 224, 78, 203, 155, 50, 177, 100, 98, 113, 182, 31, - 11, 156, 39, 235, 69, 51, 60, 13, 220, 9, 15, 198, 70, 179, 86, 187, 208, 64, 207, 70, 28, 218, 198, 57, 172, 128, 211, 64, 215, 113, 78, 139, 145, 214, 91, 56, 67, 13, 173, 119, 10, 224, 34, 186, 178, 130, 102, 109, 181, 102, 7, 103, 179, 178, 54, 232, 225, 109, 119, 9, 52, 113, 156, 164, 132, 131, 181, 114, 181, 100, 226, 144, 205, 67, 42, 177, 164, 85, 87, 203, 5, 131, 2, 10, 6, 249, 162, 200, 226, 228, 171, 67, 157, 33, 219, 170, 130, 225, 107, 166, - 176, 38, 51, 15, 113, 162, 0, 67, 195, 250, 102, 120, 55, 250, 9, 241, 36, 11, 166, 165, 242, 25, 65, 35, 134, 201, 149, 155, 224, 118, 209, 2, 49, 193, 226, 37, 198, 46, 193, 100, 173, 169, 10, 242, 127, 144, 177, 36, 128, 194, 37, 8, 224, 176, 118, 67, 33, 1, 66, 41, 100, 57, 173, 156, 211, 230, 247, 182, 145, 173, 181, 65, 90, 33, 2, 77, 0, 118, 206, 108, 19, 178, 187, 4, 226, 255, 142, 174, 139, 182, 184, 154, 1, 97, 148, 98, 208, 37, 196, 187, - 197, 185, 161, 198, 104, 171, 89, 139, 101, 146, 83, 176, 67, 196, 65, 14, 224, 66, 68, 145, 38, 64, 23, 18, 39, 146, 55, 2, 80, 227, 13, 58, 133, 193, 147, 50, 68, 30, 19, 166, 189, 27, 249, 132, 137, 167, 240, 120, 93, 12, 65, 178, 54, 12, 147, 48, 192, 32, 229, 253, 17, 83, 136, 139, 196, 155, 212, 234, 48, 56, 97, 179, 7, 39, 241, 48, 149, 12, 42, 106, 57, 99, 51, 27, 232, 2, 127, 74, 133, 240, 101, 187, 177, 64, 183, 56, 129, 193, 101, 4, - 77, 189, 89, 8, 112, 191, 5, 245, 154, 227, 97, 181, 20, 92, 177, 105, 26, 87, 77, 154, 169, 16, 44, 80, 194, 52, 181, 44, 134, 100, 192, 253, 178, 78, 97, 112, 96, 5, 131, 225, 49, 194, 159, 39, 193, 56, 184, 22, 12, 143, 24, 192, 235, 90, 76, 164, 225, 186, 135, 39, 132, 147, 131, 174, 130, 185, 156, 102, 236, 118, 58, 213, 226, 236, 58, 214, 45, 176, 23, 91, 203, 119, 157, 223, 136, 12, 90, 157, 20, 185, 5, 213, 64, 142, 158, 234, 106, 180, 159, 195, - 147, 101, 116, 218, 28, 178, 154, 56, 143, 216, 237, 148, 25, 128, 38, 198, 66, 195, 44, 16, 224, 161, 152, 2, 230, 238, 110, 199, 9, 139, 35, 7, 84, 66, 24, 188, 27, 36, 74, 8, 224, 200, 139, 47, 109, 3, 95, 202, 153, 148, 26, 33, 195, 202, 57, 206, 34, 233, 20, 60, 149, 4, 193, 89, 71, 21, 80, 229, 25, 141, 114, 224, 102, 208, 26, 155, 224, 104, 32, 161, 156, 139, 110, 10, 197, 247, 203, 3, 11, 175, 122, 63, 201, 68, 167, 21, 150, 95, 52, 87, - 69, 67, 63, 79, 179, 245, 6, 150, 133, 45, 4, 204, 153, 86, 166, 222, 108, 117, 90, 17, 148, 26, 44, 115, 120, 62, 100, 17, 166, 112, 73, 75, 181, 192, 218, 162, 123, 94, 21, 218, 10, 93, 105, 73, 62, 93, 162, 108, 38, 205, 54, 211, 45, 90, 39, 177, 93, 194, 72, 150, 91, 155, 47, 199, 71, 185, 217, 238, 183, 103, 144, 94, 97, 225, 9, 33, 244, 40, 108, 25, 15, 94, 10, 108, 129, 141, 180, 149, 55, 133, 196, 7, 224, 97, 202, 16, 60, 161, 193, 206, - 250, 19, 73, 51, 85, 51, 177, 66, 87, 166, 45, 214, 149, 149, 20, 226, 168, 64, 54, 10, 255, 243, 208, 200, 150, 82, 251, 231, 120, 140, 127, 72, 87, 81, 90, 38, 49, 64, 14, 5, 156, 213, 10, 86, 41, 192, 57, 14, 124, 72, 22, 80, 129, 110, 88, 163, 118, 133, 148, 193, 22, 150, 49, 177, 69, 184, 88, 18, 202, 56, 35, 219, 21, 130, 227, 118, 67, 84, 225, 128, 53, 112, 87, 88, 101, 80, 86, 65, 62, 116, 5, 75, 51, 98, 57, 231, 16, 252, 93, 16, - 177, 69, 78, 139, 165, 200, 194, 152, 130, 251, 66, 132, 129, 251, 73, 181, 16, 221, 22, 174, 46, 132, 35, 234, 12, 163, 148, 20, 250, 49, 241, 86, 99, 99, 244, 22, 86, 218, 242, 134, 0, 2, 58, 9, 161, 108, 74, 108, 184, 159, 39, 51, 66, 69, 73, 153, 134, 54, 72, 6, 203, 14, 141, 7, 216, 105, 131, 11, 176, 192, 134, 143, 7, 220, 229, 27, 28, 102, 61, 171, 169, 15, 95, 43, 186, 226, 240, 202, 13, 217, 182, 43, 145, 115, 35, 110, 184, 58, 29, 10, - 15, 207, 41, 220, 184, 165, 28, 240, 234, 150, 192, 143, 143, 90, 130, 5, 173, 118, 18, 116, 134, 91, 56, 15, 242, 250, 46, 249, 136, 35, 162, 213, 117, 229, 14, 88, 149, 225, 121, 7, 159, 141, 197, 42, 3, 143, 77, 252, 119, 52, 126, 98, 252, 86, 140, 143, 231, 34, 33, 18, 220, 10, 158, 122, 75, 168, 82, 208, 39, 29, 11, 80, 90, 168, 100, 176, 246, 179, 51, 66, 53, 45, 84, 59, 56, 167, 169, 90, 57, 45, 193, 13, 241, 120, 248, 97, 29, 74, 15, 169, - 254, 114, 215, 77, 206, 115, 252, 199, 45, 210, 209, 15, 143, 126, 162, 186, 158, 27, 201, 7, 78, 55, 246, 251, 207, 162, 64, 78, 173, 211, 128, 37, 25, 103, 64, 129, 192, 65, 90, 50, 146, 196, 19, 87, 205, 212, 68, 200, 78, 154, 113, 152, 156, 184, 89, 194, 152, 146, 71, 215, 212, 11, 14, 198, 32, 224, 150, 22, 241, 112, 107, 95, 14, 90, 74, 60, 121, 190, 202, 105, 161, 24, 170, 130, 227, 104, 109, 53, 228, 187, 34, 115, 9, 95, 60, 7, 73, 40, 216, 82, - 143, 52, 205, 81, 176, 169, 137, 100, 191, 38, 13, 134, 127, 233, 66, 193, 215, 48, 14, 75, 3, 86, 90, 74, 58, 213, 41, 8, 62, 64, 114, 58, 88, 74, 57, 204, 33, 68, 232, 19, 228, 138, 11, 84, 170, 74, 78, 24, 152, 209, 242, 27, 0, 34, 221, 73, 37, 136, 2, 54, 70, 26, 109, 19, 246, 76, 242, 191, 141, 137, 42, 94, 87, 89, 33, 7, 131, 35, 93, 79, 217, 29, 28, 108, 1, 192, 184, 80, 216, 179, 167, 2, 107, 212, 192, 106, 230, 161, 234, 26, - 170, 97, 65, 194, 214, 219, 89, 131, 128, 19, 208, 200, 123, 121, 218, 196, 9, 164, 145, 16, 74, 23, 116, 202, 137, 185, 29, 2, 155, 8, 0, 134, 54, 25, 184, 90, 218, 136, 71, 96, 85, 228, 160, 193, 127, 74, 193, 59, 161, 160, 57, 204, 44, 223, 149, 174, 140, 117, 152, 216, 128, 36, 85, 156, 131, 172, 57, 66, 112, 148, 210, 75, 91, 1, 153, 76, 204, 33, 96, 114, 244, 17, 128, 133, 2, 75, 108, 181, 80, 112, 132, 46, 234, 242, 28, 196, 178, 95, 78, 216, - 148, 193, 62, 160, 154, 169, 101, 105, 61, 11, 27, 11, 105, 251, 109, 196, 195, 185, 240, 114, 200, 129, 26, 86, 14, 63, 236, 63, 252, 167, 162, 34, 169, 88, 74, 77, 13, 161, 30, 164, 230, 81, 62, 202, 167, 242, 69, 250, 98, 125, 106, 223, 16, 223, 131, 190, 121, 210, 155, 2, 255, 151, 244, 10, 23, 21, 21, 1, 87, 36, 92, 81, 112, 69, 195, 21, 3, 87, 44, 92, 113, 112, 197, 195, 149, 0, 87, 34, 92, 73, 112, 37, 195, 37, 209, 69, 16, 138, 104, 192, - 139, 135, 190, 158, 212, 0, 234, 118, 106, 52, 149, 7, 169, 55, 159, 122, 139, 82, 169, 230, 171, 84, 17, 170, 72, 85, 148, 42, 70, 21, 167, 74, 82, 165, 168, 250, 171, 104, 85, 166, 106, 156, 106, 102, 119, 114, 40, 178, 40, 242, 40, 50, 41, 114, 225, 69, 81, 6, 184, 40, 121, 236, 24, 34, 101, 60, 145, 47, 25, 108, 209, 147, 234, 77, 245, 163, 6, 130, 77, 238, 164, 210, 169, 123, 168, 28, 170, 128, 210, 2, 62, 79, 185, 168, 85, 212, 219, 212, 103, 84, - 132, 74, 26, 15, 255, 142, 114, 79, 248, 233, 37, 143, 143, 79, 84, 224, 243, 99, 248, 102, 49, 62, 203, 137, 110, 196, 209, 18, 225, 7, 223, 16, 73, 34, 99, 82, 68, 123, 124, 135, 180, 7, 145, 153, 130, 49, 37, 252, 248, 255, 183, 111, 136, 125, 125, 190, 159, 143, 192, 231, 51, 99, 235, 50, 152, 30, 95, 237, 152, 28, 255, 167, 1, 123, 173, 177, 191, 191, 56, 203, 126, 223, 26, 67, 231, 170, 70, 227, 242, 95, 45, 252, 184, 199, 234, 109, 167, 26, 126, 217, - 121, 244, 147, 133, 39, 15, 255, 49, 189, 116, 75, 124, 243, 220, 13, 191, 141, 29, 177, 237, 95, 207, 13, 222, 179, 216, 152, 178, 117, 240, 5, 122, 253, 172, 241, 179, 183, 127, 119, 38, 111, 247, 130, 39, 218, 62, 186, 237, 124, 251, 105, 235, 228, 166, 182, 139, 239, 184, 143, 184, 166, 46, 179, 244, 110, 89, 91, 99, 156, 115, 85, 255, 211, 23, 7, 216, 103, 38, 205, 80, 245, 57, 105, 137, 49, 24, 114, 213, 63, 124, 159, 28, 231, 221, 79, 219, 114, 126, 147, 98, - 46, 109, 207, 155, 121, 212, 49, 219, 244, 202, 161, 246, 200, 177, 197, 109, 81, 15, 253, 228, 78, 62, 92, 211, 148, 176, 230, 135, 181, 77, 247, 89, 150, 109, 204, 63, 118, 96, 231, 199, 227, 174, 238, 122, 253, 51, 203, 137, 95, 57, 103, 156, 213, 124, 152, 124, 236, 212, 35, 185, 135, 254, 246, 122, 230, 201, 97, 217, 212, 153, 201, 79, 78, 62, 190, 191, 47, 115, 112, 79, 211, 197, 205, 183, 223, 185, 119, 211, 212, 63, 53, 238, 248, 80, 189, 166, 121, 219, 242, 109, - 17, 105, 113, 11, 163, 117, 27, 79, 38, 237, 27, 218, 153, 184, 225, 233, 185, 220, 168, 158, 165, 213, 15, 255, 109, 48, 243, 86, 238, 136, 170, 45, 139, 243, 78, 213, 198, 204, 254, 88, 181, 139, 62, 188, 236, 238, 148, 163, 95, 123, 220, 27, 102, 15, 105, 218, 18, 179, 166, 125, 207, 203, 247, 180, 109, 235, 120, 229, 64, 108, 253, 189, 87, 41, 245, 162, 181, 241, 207, 247, 95, 214, 227, 211, 157, 201, 179, 230, 141, 200, 181, 198, 253, 209, 98, 124, 78, 53, 195, 240, - 207, 139, 147, 107, 106, 244, 140, 101, 208, 137, 76, 214, 61, 145, 210, 95, 248, 178, 49, 198, 242, 248, 26, 213, 192, 183, 46, 198, 61, 53, 109, 175, 250, 251, 125, 39, 215, 179, 229, 157, 91, 123, 253, 123, 219, 110, 113, 238, 194, 237, 63, 158, 29, 124, 90, 95, 50, 226, 163, 95, 124, 55, 247, 200, 179, 108, 105, 219, 181, 135, 153, 141, 101, 31, 76, 110, 202, 22, 168, 93, 171, 206, 101, 238, 108, 203, 91, 115, 118, 194, 241, 198, 19, 185, 214, 189, 135, 86, 95, 187, - 120, 236, 200, 172, 78, 115, 193, 143, 39, 109, 247, 22, 45, 52, 189, 113, 112, 219, 204, 143, 248, 17, 81, 133, 159, 15, 142, 188, 71, 87, 154, 240, 218, 129, 185, 201, 167, 199, 206, 142, 46, 127, 45, 47, 226, 174, 148, 148, 196, 221, 191, 163, 147, 14, 164, 54, 85, 79, 219, 228, 230, 232, 248, 182, 170, 237, 47, 183, 51, 31, 244, 184, 122, 230, 55, 203, 14, 156, 28, 126, 199, 178, 131, 235, 55, 175, 61, 254, 78, 191, 220, 77, 143, 204, 79, 222, 60, 50, 103, 70, - 243, 214, 55, 44, 59, 90, 104, 215, 182, 47, 183, 108, 218, 243, 66, 210, 185, 45, 145, 47, 28, 222, 32, 100, 21, 31, 253, 247, 155, 117, 135, 95, 250, 197, 176, 143, 163, 92, 125, 79, 241, 189, 18, 13, 159, 45, 200, 49, 46, 125, 96, 150, 53, 121, 237, 244, 89, 115, 18, 63, 236, 209, 254, 146, 47, 126, 201, 93, 235, 168, 132, 13, 203, 99, 159, 40, 92, 162, 254, 230, 240, 170, 184, 167, 171, 47, 168, 126, 121, 189, 53, 198, 252, 216, 52, 253, 229, 127, 152, 216, - 39, 103, 143, 177, 12, 248, 87, 76, 141, 173, 118, 96, 219, 245, 79, 210, 143, 120, 166, 207, 249, 40, 229, 189, 9, 167, 77, 220, 217, 237, 87, 175, 126, 189, 123, 81, 193, 238, 173, 253, 142, 46, 90, 63, 179, 99, 213, 177, 99, 191, 93, 114, 104, 229, 222, 214, 19, 247, 79, 185, 112, 118, 210, 183, 166, 157, 135, 76, 211, 118, 253, 229, 116, 76, 211, 131, 15, 141, 217, 56, 254, 163, 244, 228, 19, 165, 3, 19, 222, 188, 52, 33, 114, 204, 204, 57, 81, 121, 111, 127, - 61, 243, 108, 229, 89, 211, 218, 175, 23, 217, 70, 55, 236, 54, 23, 61, 187, 137, 249, 199, 109, 174, 170, 93, 43, 14, 115, 169, 99, 206, 85, 79, 105, 172, 75, 122, 47, 178, 56, 113, 231, 246, 190, 17, 119, 140, 26, 22, 93, 185, 59, 103, 199, 223, 211, 18, 155, 55, 254, 97, 250, 230, 244, 168, 89, 155, 102, 188, 234, 59, 222, 58, 250, 195, 131, 77, 226, 242, 147, 25, 131, 215, 157, 121, 116, 125, 171, 241, 207, 195, 46, 24, 190, 120, 113, 213, 44, 103, 194, 18, - 107, 196, 95, 99, 226, 95, 124, 112, 76, 143, 243, 110, 83, 172, 163, 247, 52, 42, 250, 169, 9, 123, 26, 251, 204, 217, 118, 110, 93, 250, 134, 199, 239, 31, 184, 37, 233, 207, 139, 14, 255, 33, 121, 247, 209, 207, 183, 126, 125, 106, 238, 237, 103, 63, 78, 108, 59, 124, 228, 119, 249, 231, 218, 190, 189, 178, 233, 116, 181, 205, 245, 209, 144, 247, 251, 238, 158, 255, 232, 176, 237, 151, 62, 173, 91, 207, 213, 21, 111, 237, 255, 207, 233, 113, 11, 237, 179, 212, 190, 119, - 115, 98, 170, 102, 36, 170, 122, 250, 150, 179, 191, 55, 175, 211, 95, 57, 226, 171, 97, 52, 31, 90, 250, 214, 159, 75, 88, 241, 213, 225, 228, 227, 21, 174, 168, 137, 173, 155, 34, 179, 152, 97, 166, 87, 47, 247, 157, 121, 176, 172, 216, 92, 242, 113, 157, 237, 129, 9, 179, 14, 173, 59, 53, 253, 216, 201, 170, 196, 179, 227, 190, 201, 57, 241, 107, 237, 186, 93, 127, 253, 251, 242, 157, 103, 230, 125, 184, 177, 184, 211, 215, 148, 57, 232, 66, 115, 243, 51, 173, 59, - 222, 205, 92, 178, 73, 251, 151, 85, 155, 135, 70, 143, 57, 184, 99, 73, 204, 241, 247, 135, 79, 59, 83, 177, 199, 116, 242, 206, 145, 115, 170, 54, 109, 155, 192, 236, 141, 24, 88, 253, 216, 210, 116, 238, 238, 95, 239, 78, 220, 188, 114, 81, 210, 219, 3, 207, 70, 79, 247, 126, 29, 49, 2, 235, 237, 194, 142, 55, 58, 82, 228, 218, 185, 175, 238, 240, 243, 42, 185, 238, 70, 60, 113, 247, 174, 60, 185, 246, 214, 191, 162, 159, 17, 39, 215, 95, 237, 134, 101, 231, - 99, 229, 26, 220, 231, 92, 237, 166, 84, 185, 14, 15, 250, 96, 214, 251, 49, 114, 45, 190, 191, 108, 156, 74, 45, 215, 247, 11, 151, 151, 123, 51, 228, 58, 127, 109, 229, 234, 236, 49, 114, 189, 95, 113, 105, 64, 11, 242, 195, 191, 12, 68, 159, 42, 63, 135, 112, 252, 228, 196, 36, 125, 18, 141, 252, 240, 111, 197, 53, 15, 127, 188, 95, 212, 77, 106, 23, 62, 92, 134, 191, 147, 86, 23, 238, 75, 249, 65, 146, 131, 238, 167, 34, 115, 66, 6, 188, 208, 119, 196, - 80, 159, 92, 233, 158, 30, 245, 216, 48, 182, 238, 21, 148, 27, 245, 123, 234, 203, 71, 222, 78, 146, 109, 49, 167, 96, 209, 132, 100, 217, 22, 219, 95, 204, 202, 136, 151, 109, 113, 58, 157, 38, 229, 21, 241, 134, 157, 175, 213, 43, 182, 120, 172, 224, 249, 23, 98, 186, 145, 239, 53, 144, 175, 255, 53, 105, 60, 186, 191, 36, 31, 218, 225, 201, 255, 97, 239, 188, 163, 163, 170, 190, 61, 126, 38, 5, 120, 116, 144, 98, 168, 9, 132, 72, 72, 144, 68, 98, 32, 9, - 72, 208, 208, 20, 33, 20, 17, 65, 32, 52, 105, 63, 32, 82, 164, 75, 128, 80, 5, 149, 18, 127, 72, 141, 52, 193, 208, 132, 160, 84, 9, 189, 63, 186, 5, 130, 132, 242, 11, 221, 160, 191, 80, 132, 168, 111, 239, 185, 123, 51, 223, 101, 24, 38, 239, 159, 247, 214, 122, 111, 238, 90, 135, 249, 48, 249, 204, 57, 231, 238, 83, 239, 100, 238, 36, 200, 117, 253, 238, 205, 186, 124, 218, 75, 234, 23, 184, 100, 193, 37, 111, 169, 223, 196, 252, 21, 248, 143, 229, 61, - 243, 208, 242, 205, 242, 152, 253, 254, 57, 214, 218, 153, 38, 229, 115, 172, 162, 107, 62, 187, 252, 167, 29, 79, 91, 83, 108, 46, 94, 195, 231, 177, 189, 86, 207, 189, 222, 114, 30, 27, 147, 55, 244, 241, 148, 243, 104, 25, 221, 122, 45, 159, 31, 199, 57, 238, 98, 202, 102, 254, 57, 199, 217, 163, 197, 129, 116, 93, 243, 127, 157, 250, 242, 235, 92, 6, 199, 57, 172, 242, 160, 62, 90, 255, 85, 43, 183, 21, 212, 245, 191, 95, 112, 34, 127, 130, 212, 222, 231, 188, - 226, 150, 46, 100, 230, 62, 53, 240, 234, 201, 227, 204, 220, 231, 250, 47, 89, 201, 183, 223, 218, 251, 220, 151, 231, 187, 69, 48, 115, 159, 235, 56, 118, 216, 100, 102, 238, 115, 158, 93, 102, 116, 102, 46, 67, 169, 119, 173, 150, 83, 153, 249, 207, 169, 87, 77, 29, 52, 152, 153, 239, 39, 105, 29, 82, 187, 48, 179, 15, 165, 138, 41, 11, 254, 98, 46, 71, 41, 115, 195, 112, 251, 13, 47, 252, 23, 66, 122, 126, 93, 230, 30, 51, 127, 25, 210, 140, 79, 191, 229, - 143, 236, 152, 138, 28, 171, 178, 15, 249, 230, 73, 195, 223, 157, 82, 33, 242, 83, 190, 45, 209, 254, 21, 252, 105, 207, 63, 190, 192, 236, 75, 41, 114, 205, 196, 242, 204, 126, 148, 94, 173, 153, 211, 136, 247, 58, 252, 23, 207, 60, 58, 149, 93, 205, 207, 243, 151, 180, 123, 13, 30, 87, 147, 227, 195, 31, 109, 218, 211, 184, 104, 45, 126, 158, 199, 226, 201, 110, 227, 91, 123, 74, 220, 181, 253, 91, 82, 251, 167, 231, 88, 229, 76, 241, 177, 218, 191, 46, 165, 140, - 255, 70, 251, 115, 27, 254, 103, 228, 200, 61, 54, 105, 195, 169, 35, 61, 214, 218, 164, 13, 63, 184, 86, 245, 117, 157, 55, 252, 119, 239, 127, 178, 103, 27, 219, 235, 195, 119, 11, 74, 27, 214, 248, 171, 238, 84, 47, 105, 195, 98, 77, 7, 247, 243, 146, 54, 124, 117, 68, 157, 38, 30, 210, 134, 157, 186, 167, 245, 242, 144, 54, 156, 179, 254, 243, 81, 249, 165, 13, 211, 239, 100, 20, 240, 148, 54, 28, 191, 61, 100, 172, 182, 97, 192, 188, 38, 37, 61, 164, 13, - 95, 121, 212, 170, 130, 182, 225, 128, 3, 15, 188, 181, 13, 235, 87, 13, 217, 165, 109, 24, 157, 60, 104, 183, 182, 225, 196, 155, 145, 237, 180, 13, 207, 22, 121, 216, 89, 99, 134, 135, 198, 111, 219, 151, 49, 251, 231, 254, 105, 149, 217, 188, 188, 21, 191, 218, 148, 146, 107, 61, 59, 126, 26, 171, 7, 221, 94, 251, 192, 75, 98, 181, 119, 198, 144, 72, 237, 239, 123, 83, 55, 173, 243, 146, 88, 141, 139, 57, 63, 90, 231, 149, 204, 106, 231, 126, 211, 254, 126, 241, - 219, 69, 193, 218, 223, 111, 28, 219, 25, 166, 253, 61, 112, 212, 245, 251, 26, 171, 161, 75, 3, 190, 242, 148, 88, 157, 40, 145, 53, 93, 99, 213, 240, 151, 110, 125, 61, 36, 86, 93, 179, 214, 36, 112, 156, 184, 109, 166, 110, 111, 117, 81, 251, 254, 4, 159, 208, 156, 252, 18, 183, 164, 173, 89, 133, 2, 36, 110, 151, 215, 20, 11, 47, 44, 113, 91, 248, 97, 234, 122, 15, 137, 219, 189, 233, 145, 191, 228, 147, 184, 101, 53, 168, 198, 183, 34, 218, 251, 126, 250, - 129, 162, 163, 248, 92, 184, 239, 175, 24, 120, 184, 24, 51, 247, 253, 157, 147, 203, 84, 102, 135, 251, 254, 236, 73, 117, 251, 114, 221, 184, 239, 63, 190, 124, 41, 137, 29, 238, 147, 137, 103, 51, 191, 102, 246, 165, 228, 191, 175, 124, 53, 102, 238, 251, 61, 102, 117, 159, 207, 204, 125, 127, 196, 129, 195, 43, 57, 31, 238, 251, 243, 26, 165, 218, 184, 14, 220, 247, 187, 249, 126, 63, 157, 29, 238, 251, 187, 142, 164, 248, 241, 243, 124, 14, 153, 111, 21, 56, 203, 252, - 2, 165, 14, 139, 155, 143, 101, 167, 58, 199, 211, 86, 190, 2, 199, 32, 144, 210, 111, 249, 126, 180, 199, 144, 191, 188, 111, 230, 209, 181, 203, 152, 131, 40, 197, 191, 93, 46, 191, 125, 13, 161, 180, 184, 242, 63, 236, 183, 207, 241, 27, 80, 62, 177, 197, 249, 11, 2, 204, 139, 148, 154, 246, 79, 191, 201, 92, 139, 210, 233, 94, 85, 7, 240, 121, 133, 80, 250, 53, 54, 177, 60, 115, 40, 165, 89, 23, 50, 107, 48, 191, 68, 105, 208, 230, 22, 87, 61, 164, 223, - 140, 238, 208, 231, 91, 174, 15, 119, 174, 168, 187, 63, 21, 99, 231, 101, 74, 175, 175, 171, 116, 137, 153, 215, 6, 191, 195, 15, 74, 176, 95, 135, 210, 128, 144, 114, 135, 249, 121, 30, 179, 73, 241, 39, 50, 153, 35, 184, 237, 26, 175, 231, 143, 174, 155, 72, 74, 27, 239, 237, 59, 206, 28, 69, 105, 228, 79, 59, 75, 112, 221, 180, 255, 150, 92, 25, 179, 191, 169, 151, 205, 94, 70, 98, 5, 171, 255, 242, 109, 141, 113, 161, 174, 215, 159, 155, 241, 126, 129, 218, - 143, 27, 30, 253, 249, 7, 29, 243, 1, 103, 250, 122, 242, 207, 185, 31, 111, 238, 112, 188, 190, 246, 227, 168, 127, 103, 45, 227, 248, 114, 223, 153, 219, 226, 61, 155, 174, 143, 1, 219, 203, 93, 249, 251, 24, 211, 250, 173, 162, 250, 13, 167, 17, 203, 110, 116, 101, 171, 126, 220, 119, 162, 235, 186, 174, 95, 214, 200, 54, 205, 116, 93, 57, 58, 115, 79, 188, 174, 43, 93, 190, 61, 180, 67, 199, 217, 207, 17, 161, 131, 60, 164, 126, 137, 223, 221, 108, 162, 245, 27, - 250, 217, 131, 3, 30, 82, 191, 113, 15, 182, 173, 224, 215, 242, 56, 171, 180, 109, 198, 114, 221, 203, 124, 85, 231, 216, 60, 206, 135, 199, 89, 239, 158, 213, 238, 241, 107, 121, 156, 197, 103, 85, 60, 206, 175, 229, 113, 230, 121, 48, 181, 143, 206, 73, 69, 202, 254, 144, 205, 62, 143, 173, 198, 30, 245, 167, 235, 156, 212, 107, 199, 173, 26, 252, 60, 143, 173, 75, 43, 123, 76, 96, 230, 177, 149, 52, 238, 81, 33, 62, 15, 30, 91, 223, 236, 43, 22, 196, 117, 224, - 177, 21, 48, 35, 223, 143, 186, 174, 28, 28, 92, 116, 136, 174, 43, 195, 198, 248, 71, 120, 252, 45, 126, 15, 41, 126, 105, 212, 99, 185, 156, 12, 137, 95, 35, 142, 95, 196, 179, 227, 199, 49, 27, 120, 120, 196, 102, 109, 211, 218, 243, 11, 71, 234, 60, 126, 171, 112, 179, 37, 58, 143, 31, 91, 249, 7, 127, 222, 222, 30, 179, 61, 141, 218, 215, 208, 185, 169, 217, 206, 66, 207, 107, 204, 194, 50, 103, 221, 211, 152, 125, 238, 209, 191, 96, 73, 137, 153, 247, 165, - 231, 219, 122, 72, 204, 234, 44, 127, 247, 53, 93, 139, 253, 171, 60, 156, 168, 115, 211, 202, 129, 197, 249, 47, 200, 218, 99, 182, 235, 154, 45, 210, 91, 98, 86, 178, 245, 198, 153, 222, 18, 179, 77, 222, 187, 195, 61, 36, 102, 245, 223, 40, 186, 92, 231, 241, 94, 91, 194, 186, 61, 109, 238, 198, 248, 12, 90, 21, 179, 63, 182, 144, 205, 94, 7, 95, 63, 43, 62, 13, 40, 37, 71, 185, 238, 95, 231, 139, 134, 84, 212, 254, 95, 192, 43, 230, 162, 198, 170, 84, - 157, 191, 166, 121, 72, 172, 214, 135, 251, 242, 183, 18, 216, 99, 101, 230, 47, 245, 249, 251, 250, 251, 61, 149, 127, 130, 202, 231, 115, 137, 174, 98, 123, 178, 46, 164, 213, 119, 221, 62, 243, 31, 166, 46, 210, 50, 187, 191, 54, 234, 186, 182, 207, 237, 225, 233, 213, 92, 237, 187, 180, 252, 242, 95, 209, 254, 175, 176, 205, 218, 255, 73, 249, 246, 58, 190, 226, 186, 252, 152, 141, 187, 127, 209, 242, 15, 213, 138, 26, 166, 239, 203, 108, 47, 51, 232, 77, 221, 171, 109, - 234, 157, 112, 76, 199, 84, 147, 142, 119, 236, 237, 199, 253, 163, 82, 246, 75, 75, 249, 145, 251, 199, 177, 124, 63, 77, 214, 117, 254, 72, 64, 233, 3, 186, 118, 29, 244, 155, 244, 100, 157, 223, 190, 50, 187, 0, 151, 195, 253, 227, 104, 131, 102, 125, 248, 181, 220, 63, 82, 54, 52, 204, 247, 180, 183, 244, 244, 252, 226, 232, 252, 234, 22, 181, 217, 203, 143, 174, 106, 157, 95, 43, 74, 190, 79, 59, 191, 226, 25, 159, 20, 160, 212, 176, 51, 189, 158, 82, 64, 47, - 43, 245, 238, 99, 165, 234, 195, 173, 52, 102, 188, 149, 134, 108, 176, 210, 141, 205, 86, 42, 126, 208, 74, 125, 190, 183, 210, 11, 63, 90, 105, 183, 164, 107, 255, 178, 146, 251, 112, 31, 238, 195, 125, 184, 15, 247, 225, 62, 220, 135, 251, 112, 31, 238, 227, 127, 239, 72, 245, 183, 153, 184, 59, 54, 147, 70, 143, 209, 244, 120, 198, 203, 211, 100, 16, 251, 211, 149, 228, 118, 122, 60, 74, 105, 51, 165, 234, 244, 255, 131, 118, 215, 195, 156, 32, 103, 47, 251, 244, 156, - 47, 165, 12, 250, 127, 218, 30, 111, 179, 146, 210, 246, 198, 158, 166, 148, 183, 167, 89, 77, 143, 103, 152, 41, 221, 166, 159, 207, 161, 199, 194, 77, 60, 205, 209, 70, 158, 38, 135, 120, 52, 165, 33, 252, 28, 187, 244, 186, 5, 196, 87, 41, 121, 81, 138, 38, 47, 35, 137, 92, 226, 68, 74, 39, 110, 122, 155, 24, 122, 76, 167, 215, 182, 165, 199, 236, 18, 249, 140, 239, 86, 111, 19, 76, 222, 85, 122, 110, 58, 61, 87, 129, 203, 33, 190, 74, 101, 189, 203, 249, - 208, 207, 252, 41, 53, 39, 126, 72, 254, 109, 122, 236, 65, 105, 25, 149, 149, 64, 121, 167, 19, 15, 167, 60, 114, 232, 53, 241, 244, 88, 152, 243, 165, 84, 143, 82, 48, 165, 12, 42, 51, 172, 177, 117, 197, 90, 138, 242, 201, 38, 111, 25, 253, 63, 135, 242, 247, 167, 199, 127, 80, 218, 75, 201, 119, 163, 183, 241, 162, 115, 56, 67, 63, 191, 75, 229, 164, 114, 93, 216, 39, 207, 139, 126, 214, 219, 199, 102, 98, 40, 37, 82, 74, 160, 114, 250, 208, 99, 28, 165, - 104, 74, 67, 232, 255, 201, 148, 222, 37, 238, 65, 169, 228, 135, 198, 196, 210, 99, 115, 74, 77, 41, 189, 206, 55, 175, 150, 252, 251, 111, 79, 140, 201, 254, 127, 113, 252, 79, 143, 4, 247, 225, 62, 220, 135, 251, 112, 31, 238, 195, 125, 184, 15, 247, 225, 62, 220, 135, 251, 248, 191, 119, 240, 239, 1, 123, 8, 191, 83, 193, 193, 95, 16, 191, 71, 63, 61, 243, 254, 242, 166, 246, 207, 115, 208, 63, 157, 125, 140, 185, 71, 207, 251, 11, 243, 243, 252, 249, 146, 21, - 30, 22, 183, 176, 57, 152, 125, 47, 114, 11, 84, 180, 124, 102, 245, 223, 55, 14, 95, 153, 253, 161, 228, 148, 19, 127, 40, 248, 15, 11, 59, 124, 101, 246, 251, 7, 26, 19, 44, 62, 179, 250, 123, 109, 14, 95, 153, 253, 208, 32, 99, 94, 17, 159, 89, 253, 241, 224, 143, 7, 127, 99, 176, 49, 173, 197, 103, 86, 127, 108, 65, 135, 175, 204, 254, 75, 117, 40, 126, 226, 51, 171, 95, 29, 242, 175, 14, 249, 119, 168, 107, 204, 96, 241, 153, 213, 175, 239, 233, 240, - 149, 217, 255, 103, 148, 49, 83, 196, 103, 86, 63, 11, 234, 147, 5, 245, 153, 212, 216, 152, 133, 226, 51, 171, 255, 98, 17, 135, 175, 204, 126, 106, 27, 74, 226, 51, 171, 127, 20, 218, 247, 40, 180, 111, 66, 59, 99, 14, 137, 207, 172, 126, 5, 47, 135, 175, 204, 254, 130, 14, 198, 92, 20, 159, 89, 253, 211, 144, 255, 105, 200, 127, 96, 39, 99, 110, 139, 207, 172, 254, 41, 232, 63, 202, 236, 243, 239, 170, 31, 137, 207, 172, 190, 31, 248, 204, 229, 42, 25, 19, - 64, 229, 124, 250, 187, 49, 129, 204, 20, 99, 223, 226, 54, 19, 33, 28, 71, 220, 76, 56, 153, 184, 157, 112, 6, 113, 119, 245, 75, 216, 76, 188, 250, 196, 99, 212, 39, 158, 38, 124, 155, 248, 51, 225, 187, 196, 75, 132, 77, 73, 155, 89, 39, 28, 77, 188, 93, 56, 129, 248, 144, 112, 26, 241, 247, 234, 63, 103, 51, 25, 90, 46, 241, 175, 196, 190, 242, 86, 208, 31, 192, 5, 42, 59, 184, 24, 112, 25, 224, 170, 192, 161, 192, 81, 192, 141, 128, 91, 2, 119, - 0, 238, 13, 60, 24, 248, 67, 224, 169, 192, 179, 129, 23, 3, 219, 231, 31, 27, 176, 133, 102, 69, 101, 7, 95, 171, 156, 123, 46, 234, 70, 237, 27, 230, 107, 181, 117, 55, 104, 235, 159, 160, 173, 149, 217, 143, 234, 98, 76, 19, 241, 153, 213, 255, 22, 198, 166, 50, 251, 191, 197, 25, 211, 81, 124, 102, 245, 171, 64, 95, 173, 2, 125, 181, 84, 119, 99, 226, 197, 103, 86, 63, 4, 242, 15, 129, 252, 99, 232, 228, 166, 137, 207, 172, 254, 8, 168, 255, 8, 168, - 255, 14, 114, 190, 16, 127, 7, 248, 29, 32, 255, 14, 144, 127, 217, 247, 140, 217, 37, 62, 179, 250, 197, 192, 47, 6, 62, 127, 190, 227, 148, 248, 204, 206, 198, 142, 179, 246, 250, 205, 215, 193, 97, 126, 185, 219, 171, 9, 229, 57, 222, 207, 202, 191, 9, 228, 191, 6, 242, 87, 102, 63, 155, 156, 57, 226, 103, 131, 191, 21, 252, 173, 224, 175, 237, 109, 76, 138, 248, 204, 174, 124, 254, 28, 203, 94, 241, 153, 157, 157, 239, 21, 63, 215, 125, 245, 150, 31, 156, 123, - 149, 220, 231, 62, 149, 242, 31, 91, 197, 42, 107, 42, 148, 117, 4, 202, 58, 2, 117, 107, 219, 151, 230, 121, 241, 153, 213, 175, 13, 235, 66, 109, 88, 23, 38, 247, 55, 38, 73, 124, 102, 245, 143, 65, 254, 199, 48, 255, 1, 52, 79, 105, 254, 3, 28, 126, 83, 232, 27, 202, 246, 121, 123, 32, 173, 127, 226, 51, 171, 191, 20, 242, 95, 10, 249, 55, 136, 55, 102, 167, 248, 204, 234, 135, 131, 31, 14, 254, 80, 114, 142, 138, 63, 52, 15, 126, 10, 57, 231, 196, - 79, 201, 131, 127, 137, 156, 59, 226, 95, 2, 191, 30, 248, 245, 192, 175, 72, 155, 146, 28, 241, 153, 213, 111, 3, 126, 27, 240, 227, 201, 41, 88, 213, 242, 227, 223, 119, 93, 159, 21, 228, 148, 23, 127, 69, 30, 252, 116, 114, 106, 137, 159, 14, 126, 67, 240, 27, 98, 253, 7, 209, 62, 71, 124, 102, 87, 249, 183, 33, 39, 86, 252, 54, 224, 183, 7, 191, 61, 248, 41, 228, 244, 21, 63, 5, 252, 214, 224, 183, 6, 255, 15, 114, 70, 139, 255, 71, 30, 252, 150, - 131, 141, 249, 88, 124, 102, 245, 235, 130, 95, 23, 252, 201, 228, 44, 17, 127, 114, 30, 252, 157, 228, 124, 39, 254, 206, 60, 248, 15, 200, 249, 65, 252, 7, 131, 93, 199, 179, 230, 16, 99, 50, 197, 103, 118, 149, 127, 79, 114, 238, 137, 223, 51, 15, 254, 66, 114, 10, 250, 91, 254, 66, 240, 235, 131, 95, 31, 252, 115, 228, 248, 138, 127, 46, 15, 126, 217, 161, 180, 70, 138, 207, 172, 126, 99, 240, 27, 131, 223, 137, 156, 55, 196, 239, 4, 254, 16, 240, 135, 128, - 127, 146, 156, 174, 226, 159, 4, 255, 115, 240, 63, 7, 191, 239, 7, 198, 12, 19, 159, 89, 253, 45, 224, 111, 1, 191, 234, 48, 99, 166, 139, 207, 236, 170, 189, 222, 33, 231, 11, 241, 223, 1, 255, 56, 248, 199, 193, 231, 207, 62, 174, 21, 159, 89, 125, 63, 240, 153, 15, 208, 147, 190, 242, 65, 215, 211, 192, 25, 192, 119, 128, 115, 128, 139, 84, 115, 112, 89, 224, 106, 192, 225, 192, 141, 128, 223, 2, 238, 1, 60, 4, 120, 42, 240, 60, 224, 20, 224, 157, 192, - 199, 170, 57, 214, 193, 139, 192, 191, 0, 123, 6, 56, 248, 57, 224, 138, 192, 65, 192, 145, 192, 45, 128, 59, 3, 247, 7, 254, 16, 120, 38, 240, 18, 224, 77, 192, 251, 128, 207, 3, 223, 4, 126, 12, 92, 228, 5, 7, 87, 2, 14, 6, 142, 2, 110, 6, 252, 46, 112, 63, 224, 17, 192, 147, 128, 103, 1, 127, 1, 188, 30, 120, 23, 240, 41, 224, 12, 224, 44, 224, 63, 129, 255, 163, 186, 131, 75, 3, 7, 2, 191, 12, 220, 16, 184, 21, 112, 103, 224, 126, - 192, 195, 129, 199, 1, 127, 2, 188, 16, 120, 29, 240, 110, 224, 31, 129, 111, 0, 63, 2, 46, 24, 232, 224, 146, 192, 149, 129, 131, 128, 163, 129, 219, 3, 119, 3, 30, 0, 60, 18, 120, 34, 240, 76, 226, 128, 252, 116, 45, 86, 51, 159, 125, 92, 63, 109, 239, 183, 40, 16, 246, 129, 129, 214, 222, 239, 44, 236, 253, 154, 209, 252, 16, 89, 195, 154, 43, 154, 193, 92, 81, 195, 56, 230, 10, 101, 246, 7, 147, 19, 43, 254, 96, 240, 107, 130, 95, 19, 252, 100, - 114, 122, 137, 159, 12, 126, 83, 240, 155, 130, 127, 157, 156, 15, 196, 191, 14, 62, 255, 89, 32, 245, 149, 217, 191, 77, 23, 33, 83, 196, 103, 86, 191, 32, 92, 7, 21, 132, 235, 160, 251, 163, 140, 153, 47, 62, 179, 250, 217, 80, 159, 108, 168, 207, 205, 209, 180, 239, 23, 159, 89, 253, 116, 240, 211, 193, 223, 63, 134, 230, 85, 241, 153, 213, 111, 14, 126, 115, 240, 249, 115, 20, 223, 139, 207, 172, 126, 59, 240, 219, 129, 223, 155, 156, 76, 241, 123, 131, 95, 0, - 226, 163, 108, 223, 251, 141, 53, 230, 119, 241, 153, 213, 95, 4, 249, 47, 130, 252, 139, 38, 80, 10, 178, 124, 102, 245, 131, 192, 15, 2, 63, 130, 156, 42, 226, 71, 128, 63, 20, 252, 161, 224, 175, 37, 231, 85, 241, 215, 130, 223, 11, 252, 94, 224, 151, 30, 71, 231, 47, 62, 179, 171, 250, 68, 147, 51, 64, 252, 232, 60, 248, 253, 200, 153, 35, 126, 63, 240, 67, 192, 15, 1, 127, 62, 57, 27, 196, 159, 159, 7, 255, 8, 57, 199, 197, 63, 2, 254, 6, 240, - 55, 128, 207, 247, 43, 220, 22, 159, 89, 125, 63, 240, 153, 243, 7, 59, 214, 190, 210, 192, 129, 192, 49, 193, 142, 185, 130, 95, 251, 180, 249, 225, 205, 96, 7, 47, 8, 206, 61, 63, 44, 162, 58, 220, 9, 182, 234, 179, 8, 234, 179, 15, 234, 163, 204, 126, 247, 9, 180, 79, 16, 159, 217, 149, 95, 61, 209, 152, 124, 53, 101, 175, 146, 232, 240, 31, 131, 255, 24, 252, 170, 19, 141, 41, 46, 62, 179, 250, 221, 193, 239, 14, 254, 36, 114, 252, 196, 159, 4, 190, - 179, 249, 106, 35, 57, 53, 197, 223, 152, 7, 63, 131, 156, 40, 241, 51, 192, 111, 8, 126, 67, 240, 253, 38, 209, 222, 84, 124, 102, 87, 245, 79, 36, 167, 149, 248, 137, 224, 59, 27, 191, 85, 38, 27, 19, 39, 62, 179, 43, 63, 141, 156, 129, 226, 167, 129, 239, 108, 254, 41, 51, 133, 214, 35, 241, 153, 213, 175, 8, 239, 169, 42, 179, 95, 123, 186, 49, 211, 196, 103, 158, 75, 156, 104, 28, 253, 240, 89, 107, 193, 40, 242, 119, 201, 107, 153, 213, 63, 98, 115, - 248, 202, 236, 55, 254, 152, 246, 235, 226, 51, 171, 31, 83, 192, 225, 43, 179, 63, 237, 51, 99, 126, 22, 159, 89, 253, 246, 176, 118, 180, 135, 181, 227, 242, 92, 90, 67, 197, 103, 86, 255, 61, 168, 255, 123, 80, 255, 166, 116, 145, 112, 95, 124, 230, 39, 125, 3, 234, 223, 16, 234, 63, 117, 158, 177, 223, 152, 234, 47, 236, 42, 255, 44, 114, 138, 139, 159, 5, 254, 21, 240, 175, 128, 127, 106, 62, 245, 57, 241, 153, 213, 191, 11, 254, 93, 240, 119, 47, 160, 185, - 76, 124, 102, 245, 7, 130, 63, 16, 252, 208, 133, 116, 93, 47, 62, 179, 250, 206, 214, 214, 106, 212, 17, 91, 136, 207, 172, 254, 73, 240, 79, 130, 127, 159, 156, 183, 197, 191, 159, 7, 255, 192, 98, 26, 11, 226, 51, 171, 127, 17, 252, 139, 224, 175, 72, 166, 235, 55, 241, 153, 93, 229, 63, 236, 11, 90, 219, 196, 103, 118, 213, 94, 23, 200, 249, 72, 252, 11, 224, 143, 134, 254, 160, 108, 191, 238, 91, 74, 107, 147, 248, 204, 234, 59, 123, 223, 44, 96, 25, 141, - 109, 241, 153, 213, 31, 4, 249, 15, 130, 252, 231, 46, 167, 125, 175, 248, 204, 234, 191, 5, 254, 91, 224, 223, 89, 65, 115, 132, 248, 204, 234, 63, 130, 250, 60, 130, 250, 92, 251, 210, 152, 67, 226, 51, 171, 159, 31, 242, 207, 15, 249, 255, 178, 210, 152, 31, 196, 103, 86, 191, 31, 228, 223, 15, 242, 127, 103, 21, 237, 133, 52, 62, 171, 28, 126, 95, 240, 251, 130, 191, 135, 156, 127, 139, 191, 7, 252, 38, 224, 55, 1, 191, 224, 87, 198, 120, 215, 178, 124, 102, - 87, 126, 43, 114, 202, 138, 223, 42, 15, 254, 92, 114, 130, 196, 159, 155, 7, 255, 34, 57, 245, 196, 191, 8, 190, 179, 185, 125, 76, 10, 173, 239, 226, 51, 187, 242, 203, 175, 166, 235, 41, 241, 153, 93, 249, 91, 200, 121, 95, 252, 45, 224, 143, 2, 127, 20, 248, 97, 107, 140, 25, 43, 62, 179, 250, 206, 230, 171, 178, 107, 141, 249, 88, 124, 102, 87, 245, 217, 68, 206, 98, 241, 55, 229, 193, 111, 179, 206, 152, 20, 241, 153, 93, 245, 159, 29, 228, 108, 22, 127, - 7, 248, 206, 126, 71, 208, 119, 61, 223, 111, 107, 249, 204, 174, 234, 83, 224, 107, 186, 222, 20, 159, 217, 149, 191, 130, 156, 27, 226, 175, 200, 131, 31, 67, 27, 205, 135, 226, 51, 171, 239, 108, 239, 202, 247, 204, 22, 14, 177, 252, 33, 224, 251, 129, 207, 92, 61, 68, 126, 63, 88, 193, 102, 194, 137, 117, 207, 217, 32, 196, 186, 62, 141, 14, 205, 103, 90, 9, 199, 132, 58, 191, 86, 237, 18, 226, 224, 213, 33, 185, 247, 162, 73, 84, 135, 199, 82, 159, 36, 168, - 143, 179, 107, 213, 157, 228, 20, 13, 181, 252, 157, 224, 87, 7, 191, 58, 248, 215, 200, 241, 21, 255, 26, 248, 11, 108, 14, 95, 153, 253, 9, 169, 180, 167, 17, 159, 89, 253, 219, 144, 255, 109, 200, 127, 224, 38, 99, 222, 16, 159, 89, 125, 127, 200, 223, 31, 242, 159, 253, 141, 49, 157, 196, 103, 86, 127, 51, 248, 155, 193, 127, 99, 179, 49, 35, 196, 103, 118, 213, 31, 248, 94, 232, 25, 226, 223, 216, 236, 188, 125, 157, 181, 215, 154, 80, 7, 255, 30, 154, 187, - 189, 10, 110, 161, 249, 235, 37, 153, 63, 183, 56, 242, 119, 118, 45, 95, 116, 43, 245, 1, 241, 153, 213, 95, 6, 245, 89, 6, 245, 223, 64, 78, 188, 248, 27, 192, 191, 0, 254, 5, 240, 63, 217, 102, 204, 100, 241, 153, 213, 111, 11, 126, 91, 240, 175, 144, 51, 79, 252, 43, 224, 251, 64, 253, 125, 160, 254, 57, 219, 233, 154, 86, 124, 102, 245, 157, 237, 151, 250, 237, 48, 230, 160, 248, 204, 174, 206, 183, 216, 119, 180, 95, 21, 159, 89, 253, 202, 80, 159, 202, - 80, 159, 23, 119, 26, 243, 171, 248, 204, 174, 226, 83, 40, 141, 218, 163, 182, 229, 51, 187, 234, 207, 15, 200, 41, 43, 254, 3, 240, 187, 130, 223, 21, 252, 246, 187, 104, 124, 138, 207, 172, 190, 179, 249, 103, 10, 57, 13, 196, 159, 2, 254, 117, 240, 175, 131, 31, 191, 155, 230, 113, 241, 153, 213, 119, 118, 237, 63, 159, 156, 238, 226, 207, 7, 191, 40, 196, 83, 153, 253, 85, 123, 104, 191, 39, 62, 179, 250, 69, 192, 47, 2, 254, 55, 123, 141, 153, 46, 62, 179, - 250, 57, 224, 231, 128, 191, 97, 191, 49, 75, 196, 103, 118, 213, 31, 218, 29, 48, 38, 85, 124, 102, 245, 35, 192, 143, 0, 255, 19, 114, 14, 137, 255, 201, 1, 215, 241, 217, 74, 78, 166, 248, 91, 193, 119, 118, 109, 200, 223, 169, 144, 45, 62, 179, 250, 126, 224, 51, 251, 132, 89, 107, 129, 111, 132, 243, 181, 160, 106, 152, 131, 7, 134, 229, 158, 91, 66, 41, 255, 29, 97, 114, 173, 1, 101, 57, 91, 11, 58, 146, 115, 92, 252, 142, 224, 59, 91, 11, 38, 144, - 147, 33, 254, 4, 240, 203, 66, 219, 41, 179, 63, 239, 16, 237, 45, 197, 103, 86, 127, 24, 228, 63, 12, 242, 47, 113, 216, 152, 124, 47, 91, 62, 179, 250, 161, 224, 135, 130, 255, 42, 57, 101, 197, 127, 21, 252, 217, 224, 207, 6, 255, 44, 57, 47, 136, 127, 22, 252, 24, 168, 127, 12, 212, 223, 231, 168, 49, 225, 226, 51, 171, 255, 54, 92, 215, 43, 219, 199, 218, 9, 186, 198, 22, 159, 89, 253, 57, 80, 159, 57, 80, 31, 47, 186, 112, 122, 71, 124, 102, 245, - 157, 253, 142, 59, 154, 156, 190, 226, 71, 131, 239, 108, 46, 93, 71, 206, 24, 241, 215, 129, 31, 4, 231, 27, 4, 231, 123, 238, 148, 49, 51, 197, 103, 86, 223, 217, 90, 252, 231, 105, 99, 150, 138, 207, 236, 42, 255, 192, 179, 52, 102, 196, 103, 86, 223, 217, 222, 114, 54, 57, 199, 197, 159, 13, 190, 179, 223, 177, 30, 33, 231, 134, 248, 71, 192, 119, 182, 214, 243, 247, 156, 228, 136, 207, 236, 108, 108, 150, 15, 55, 79, 246, 111, 181, 194, 173, 113, 154, 16, 229, - 124, 156, 214, 15, 119, 240, 71, 225, 185, 199, 233, 52, 42, 235, 124, 184, 85, 238, 52, 40, 215, 217, 56, 77, 37, 39, 75, 252, 84, 240, 157, 141, 211, 116, 114, 60, 234, 88, 126, 58, 248, 29, 193, 239, 8, 126, 157, 31, 140, 41, 41, 62, 179, 43, 127, 22, 57, 254, 226, 207, 2, 63, 9, 252, 36, 240, 249, 123, 100, 34, 196, 103, 118, 22, 231, 14, 117, 172, 216, 38, 215, 119, 30, 219, 158, 117, 28, 188, 161, 78, 238, 216, 54, 229, 252, 235, 90, 101, 53, 133, - 178, 170, 65, 89, 213, 160, 110, 253, 201, 41, 37, 126, 255, 31, 93, 199, 54, 137, 156, 0, 241, 147, 192, 119, 246, 94, 40, 127, 119, 78, 164, 248, 187, 159, 113, 238, 206, 206, 151, 63, 99, 170, 156, 92, 55, 247, 249, 94, 161, 60, 175, 75, 254, 87, 242, 112, 190, 5, 126, 162, 125, 169, 248, 204, 234, 47, 6, 127, 49, 248, 95, 146, 243, 151, 248, 95, 130, 191, 13, 252, 109, 224, 119, 59, 71, 235, 92, 132, 229, 51, 171, 239, 244, 51, 126, 231, 41, 190, 226, 51, - 171, 159, 5, 126, 22, 248, 53, 210, 141, 105, 40, 62, 179, 250, 177, 240, 254, 100, 44, 188, 63, 57, 242, 103, 234, 187, 226, 51, 171, 223, 12, 242, 111, 6, 249, 239, 33, 103, 164, 248, 123, 192, 111, 9, 126, 75, 240, 75, 94, 52, 230, 51, 241, 153, 213, 31, 97, 115, 248, 202, 236, 127, 148, 97, 204, 118, 241, 153, 213, 159, 5, 254, 44, 240, 43, 94, 54, 230, 148, 248, 204, 234, 223, 7, 255, 62, 248, 207, 93, 53, 230, 170, 248, 204, 234, 159, 1, 255, 12, 248, - 252, 157, 78, 57, 226, 51, 59, 235, 159, 229, 34, 29, 115, 224, 139, 192, 81, 192, 205, 129, 219, 3, 247, 5, 254, 0, 120, 10, 240, 124, 96, 103, 99, 225, 235, 72, 7, 167, 71, 90, 99, 225, 94, 230, 253, 198, 122, 46, 197, 51, 141, 41, 29, 37, 123, 45, 226, 42, 81, 185, 223, 87, 143, 133, 56, 196, 66, 28, 226, 174, 25, 243, 166, 188, 150, 89, 253, 56, 136, 131, 50, 251, 105, 228, 116, 17, 63, 13, 252, 120, 240, 227, 193, 15, 161, 77, 121, 127, 241, 153, - 213, 79, 0, 63, 1, 252, 245, 228, 140, 21, 127, 61, 248, 190, 224, 251, 130, 127, 130, 156, 207, 196, 63, 1, 190, 179, 235, 8, 115, 195, 152, 213, 226, 51, 187, 202, 223, 151, 156, 125, 226, 251, 222, 112, 93, 255, 100, 114, 206, 139, 159, 12, 254, 122, 240, 215, 131, 31, 123, 147, 174, 163, 196, 103, 118, 21, 255, 245, 228, 252, 174, 241, 185, 233, 186, 62, 33, 183, 140, 201, 95, 79, 226, 127, 203, 225, 167, 129, 159, 6, 254, 93, 114, 74, 137, 127, 247, 150, 235, 248, - 20, 167, 139, 192, 26, 226, 51, 63, 233, 111, 224, 199, 130, 31, 71, 78, 3, 241, 227, 110, 187, 62, 223, 52, 114, 218, 138, 207, 220, 165, 94, 238, 190, 157, 80, 8, 206, 189, 144, 227, 181, 209, 15, 105, 159, 33, 175, 101, 86, 127, 38, 148, 197, 60, 183, 158, 99, 12, 46, 171, 103, 173, 197, 43, 163, 243, 153, 117, 194, 171, 163, 157, 175, 203, 56, 54, 183, 213, 203, 61, 54, 249, 251, 234, 254, 148, 58, 100, 64, 29, 186, 66, 29, 148, 53, 127, 254, 46, 189, 74, - 196, 53, 158, 183, 190, 155, 175, 40, 113, 105, 31, 235, 59, 20, 249, 249, 230, 62, 246, 95, 13, 217, 185, 189, 143, 245, 59, 69, 118, 248, 62, 130, 174, 194, 252, 185, 232, 113, 194, 252, 153, 225, 100, 97, 254, 12, 216, 22, 97, 254, 157, 242, 25, 97, 254, 125, 220, 101, 97, 126, 127, 239, 79, 97, 126, 47, 136, 203, 97, 230, 235, 184, 215, 132, 121, 223, 216, 77, 152, 247, 54, 19, 132, 121, 173, 95, 42, 204, 243, 234, 46, 97, 158, 91, 78, 11, 243, 60, 240, 47, - 97, 30, 35, 247, 133, 185, 63, 123, 121, 88, 204, 109, 93, 140, 89, 238, 125, 168, 196, 44, 247, 62, 188, 40, 204, 247, 62, 188, 34, 204, 247, 62, 188, 33, 204, 247, 62, 180, 87, 191, 132, 205, 244, 84, 159, 120, 144, 250, 196, 99, 133, 249, 222, 135, 143, 132, 249, 222, 135, 127, 10, 243, 189, 15, 203, 132, 249, 222, 135, 175, 133, 249, 222, 135, 239, 132, 249, 222, 135, 35, 234, 63, 71, 123, 20, 45, 151, 56, 83, 253, 10, 54, 147, 205, 172, 159, 207, 241, 180, 152, - 223, 11, 125, 78, 152, 223, 11, 245, 19, 230, 107, 225, 32, 97, 222, 111, 71, 8, 243, 254, 48, 70, 152, 251, 103, 75, 97, 238, 159, 29, 137, 139, 253, 87, 123, 103, 27, 28, 73, 113, 222, 241, 37, 246, 1, 6, 46, 62, 94, 14, 56, 48, 21, 39, 1, 18, 87, 124, 210, 73, 119, 146, 239, 136, 43, 230, 116, 146, 14, 197, 186, 147, 208, 234, 14, 82, 174, 98, 60, 218, 157, 149, 6, 205, 206, 44, 51, 179, 186, 211, 133, 36, 23, 200, 7, 40, 48, 21, 219, 161, - 66, 98, 187, 192, 54, 118, 92, 133, 73, 40, 202, 41, 59, 46, 7, 131, 141, 227, 248, 13, 98, 2, 137, 207, 1, 12, 38, 126, 137, 49, 134, 80, 21, 32, 49, 121, 121, 254, 221, 255, 153, 233, 217, 153, 93, 137, 72, 229, 162, 108, 127, 152, 218, 95, 63, 211, 211, 211, 211, 211, 221, 211, 253, 244, 211, 207, 74, 29, 134, 31, 145, 38, 25, 254, 75, 174, 38, 195, 175, 199, 187, 201, 240, 5, 242, 65, 50, 124, 128, 220, 65, 134, 79, 147, 191, 33, 195, 23, 202, 223, - 191, 70, 219, 221, 67, 63, 243, 24, 25, 186, 145, 103, 201, 208, 227, 157, 240, 90, 205, 208, 81, 108, 33, 67, 223, 242, 38, 50, 116, 119, 23, 37, 113, 132, 47, 37, 67, 231, 86, 39, 67, 127, 117, 136, 12, 221, 197, 141, 228, 235, 228, 190, 183, 37, 241, 69, 254, 183, 100, 232, 151, 254, 129, 12, 93, 214, 83, 100, 232, 169, 94, 32, 67, 71, 119, 210, 6, 205, 208, 183, 188, 145, 12, 93, 220, 69, 100, 232, 109, 46, 37, 67, 231, 54, 79, 134, 190, 244, 119, 201, - 208, 45, 223, 180, 65, 151, 201, 27, 165, 76, 62, 68, 57, 116, 182, 159, 32, 67, 63, 252, 69, 50, 116, 179, 79, 145, 161, 7, 254, 49, 25, 58, 231, 141, 199, 235, 116, 224, 119, 102, 243, 241, 90, 142, 253, 23, 253, 100, 236, 173, 24, 39, 99, 207, 218, 239, 144, 177, 7, 97, 145, 140, 253, 20, 55, 144, 177, 215, 224, 67, 100, 236, 43, 249, 107, 50, 246, 128, 124, 153, 140, 253, 5, 79, 145, 177, 151, 228, 69, 50, 230, 137, 39, 157, 192, 124, 74, 187, 62, 239, - 4, 157, 183, 219, 62, 191, 161, 50, 64, 57, 116, 41, 123, 200, 208, 99, 28, 36, 67, 71, 49, 79, 198, 252, 244, 15, 201, 208, 69, 188, 155, 12, 61, 195, 109, 100, 232, 16, 238, 34, 67, 63, 240, 121, 50, 230, 254, 15, 147, 49, 175, 255, 30, 25, 115, 240, 255, 36, 99, 254, 190, 241, 68, 205, 152, 107, 159, 79, 134, 222, 102, 136, 140, 57, 245, 111, 147, 49, 55, 185, 130, 140, 121, 208, 85, 100, 204, 113, 174, 37, 99, 238, 118, 11, 25, 243, 208, 143, 147, 49, - 7, 188, 135, 140, 249, 227, 3, 100, 204, 61, 159, 36, 99, 127, 202, 243, 39, 234, 178, 130, 95, 156, 31, 147, 225, 31, 232, 228, 215, 105, 134, 79, 157, 115, 200, 240, 253, 243, 27, 100, 248, 252, 249, 45, 50, 124, 254, 76, 145, 225, 163, 103, 142, 12, 191, 62, 33, 25, 62, 133, 174, 35, 195, 207, 207, 159, 146, 225, 155, 232, 99, 100, 248, 15, 250, 52, 25, 254, 125, 190, 66, 134, 47, 160, 99, 100, 248, 3, 250, 62, 25, 126, 130, 94, 32, 195, 55, 209, 235, 78, - 210, 12, 127, 67, 103, 159, 196, 247, 242, 6, 249, 246, 144, 177, 183, 241, 173, 100, 236, 91, 220, 79, 198, 158, 196, 57, 50, 246, 27, 198, 100, 236, 37, 188, 150, 140, 57, 220, 45, 100, 236, 1, 188, 147, 140, 253, 125, 247, 147, 177, 119, 239, 24, 25, 251, 242, 158, 37, 99, 207, 221, 203, 100, 236, 167, 59, 233, 100, 157, 79, 248, 81, 58, 155, 12, 127, 73, 23, 144, 225, 35, 105, 128, 12, 31, 71, 23, 147, 225, 171, 105, 138, 12, 223, 77, 239, 36, 195, 63, 211, - 85, 100, 248, 97, 250, 3, 50, 252, 61, 221, 68, 134, 111, 167, 15, 128, 95, 179, 169, 114, 138, 124, 83, 62, 66, 62, 81, 248, 78, 198, 129, 111, 165, 79, 145, 225, 59, 234, 254, 147, 117, 158, 97, 159, 246, 168, 138, 47, 117, 251, 220, 227, 42, 63, 160, 28, 118, 134, 47, 147, 97, 3, 182, 229, 20, 205, 176, 151, 219, 69, 134, 237, 229, 20, 25, 118, 113, 53, 50, 108, 44, 143, 144, 97, 63, 121, 61, 25, 182, 103, 31, 37, 195, 110, 237, 126, 50, 108, 20, 31, - 39, 195, 126, 239, 121, 50, 214, 199, 255, 151, 12, 59, 201, 211, 54, 234, 124, 142, 74, 62, 47, 220, 168, 229, 176, 87, 28, 34, 95, 44, 105, 190, 131, 12, 187, 193, 22, 227, 95, 34, 241, 111, 160, 28, 246, 153, 31, 32, 195, 22, 241, 46, 50, 108, 15, 238, 219, 168, 203, 7, 62, 166, 30, 161, 28, 107, 208, 223, 37, 195, 190, 229, 5, 50, 214, 226, 79, 252, 69, 205, 88, 247, 63, 139, 12, 123, 179, 11, 201, 88, 175, 188, 136, 140, 181, 233, 125, 100, 172, 179, - 219, 100, 172, 65, 7, 100, 216, 134, 29, 37, 195, 238, 235, 70, 50, 108, 186, 254, 156, 12, 123, 173, 143, 144, 97, 139, 117, 23, 25, 107, 169, 159, 37, 99, 221, 246, 1, 50, 214, 100, 191, 69, 134, 189, 196, 115, 100, 181, 22, 255, 122, 205, 176, 19, 56, 157, 12, 123, 173, 95, 33, 195, 22, 107, 128, 12, 187, 169, 221, 100, 216, 53, 93, 74, 134, 205, 210, 21, 100, 216, 3, 4, 100, 216, 38, 93, 77, 134, 157, 201, 123, 200, 88, 131, 254, 48, 25, 246, 60, 119, - 147, 97, 107, 113, 47, 25, 235, 236, 15, 146, 177, 198, 253, 40, 25, 246, 60, 63, 32, 195, 86, 231, 191, 200, 176, 35, 58, 121, 147, 102, 216, 239, 109, 38, 195, 54, 239, 151, 200, 88, 139, 223, 70, 134, 157, 204, 111, 146, 97, 163, 50, 70, 86, 182, 61, 100, 216, 222, 92, 78, 134, 221, 136, 77, 134, 189, 153, 71, 134, 61, 76, 155, 12, 219, 170, 163, 100, 216, 249, 92, 79, 198, 154, 254, 205, 100, 216, 83, 221, 186, 73, 215, 49, 248, 113, 187, 131, 12, 63, 103, - 159, 36, 195, 39, 219, 23, 201, 240, 239, 246, 48, 25, 254, 212, 158, 36, 195, 143, 219, 143, 200, 240, 187, 246, 34, 25, 254, 213, 54, 156, 202, 254, 89, 248, 116, 50, 124, 181, 93, 64, 134, 143, 184, 157, 100, 248, 93, 219, 79, 134, 79, 53, 139, 12, 191, 110, 45, 50, 124, 192, 29, 61, 85, 231, 31, 235, 41, 55, 145, 161, 107, 186, 149, 12, 189, 205, 61, 100, 232, 100, 190, 73, 134, 126, 227, 121, 50, 116, 47, 103, 159, 166, 25, 122, 149, 62, 50, 116, 38, 23, - 147, 161, 143, 186, 156, 12, 221, 81, 72, 134, 222, 233, 6, 50, 246, 182, 124, 240, 52, 221, 174, 225, 203, 237, 14, 50, 252, 190, 221, 123, 26, 251, 58, 25, 27, 60, 76, 57, 124, 195, 61, 73, 134, 15, 184, 231, 24, 7, 62, 240, 94, 34, 191, 243, 102, 41, 183, 211, 117, 156, 43, 37, 206, 153, 100, 248, 150, 187, 240, 116, 29, 7, 62, 237, 6, 201, 240, 195, 247, 54, 50, 252, 232, 205, 146, 225, 143, 206, 59, 93, 231, 19, 123, 118, 174, 161, 28, 254, 247, 222, - 203, 52, 61, 73, 243, 118, 242, 81, 225, 79, 49, 62, 246, 224, 124, 141, 140, 253, 53, 223, 38, 99, 111, 227, 211, 100, 236, 91, 124, 137, 215, 194, 199, 221, 137, 103, 104, 134, 127, 187, 179, 200, 240, 123, 247, 171, 103, 232, 248, 208, 55, 238, 160, 28, 62, 239, 198, 206, 208, 249, 129, 79, 189, 41, 202, 225, 3, 239, 10, 50, 124, 226, 45, 50, 14, 252, 13, 30, 34, 195, 63, 224, 245, 100, 248, 237, 187, 153, 12, 127, 124, 127, 193, 123, 97, 143, 228, 221, 100, 236, - 127, 252, 2, 25, 123, 127, 30, 98, 124, 248, 21, 252, 14, 229, 216, 243, 248, 239, 100, 236, 103, 252, 31, 50, 246, 130, 109, 220, 204, 54, 43, 101, 120, 30, 25, 123, 208, 118, 145, 177, 255, 238, 237, 100, 236, 189, 106, 144, 177, 111, 235, 106, 50, 246, 136, 221, 64, 198, 126, 183, 91, 201, 216, 235, 247, 151, 100, 236, 139, 252, 12, 25, 123, 30, 31, 76, 210, 151, 56, 143, 37, 114, 185, 215, 179, 100, 181, 207, 238, 76, 205, 216, 243, 184, 137, 140, 253, 101, 23, 144, - 177, 247, 112, 23, 25, 251, 224, 102, 200, 216, 3, 232, 145, 177, 159, 241, 247, 206, 212, 101, 126, 185, 148, 249, 77, 103, 234, 242, 129, 31, 197, 219, 41, 135, 63, 195, 187, 201, 179, 168, 219, 140, 3, 127, 134, 95, 34, 195, 71, 227, 35, 100, 248, 88, 124, 146, 12, 191, 135, 63, 36, 195, 7, 227, 75, 188, 47, 244, 96, 199, 159, 165, 25, 122, 134, 51, 200, 208, 183, 252, 50, 25, 115, 255, 237, 100, 232, 232, 46, 78, 88, 230, 185, 7, 200, 208, 135, 92, 73, 134, - 238, 229, 40, 25, 122, 161, 119, 157, 165, 239, 11, 191, 138, 127, 70, 57, 244, 93, 127, 69, 86, 122, 42, 50, 244, 90, 143, 147, 161, 67, 251, 15, 176, 140, 91, 42, 50, 110, 57, 238, 108, 252, 87, 192, 38, 229, 172, 127, 243, 217, 72, 115, 83, 229, 232, 249, 199, 85, 222, 76, 254, 35, 225, 9, 242, 117, 194, 1, 249, 70, 225, 107, 200, 127, 44, 252, 126, 242, 159, 8, 127, 146, 124, 139, 240, 195, 228, 247, 11, 255, 136, 124, 155, 240, 235, 183, 104, 190, 93, 120, - 128, 252, 49, 225, 3, 228, 143, 11, 47, 109, 209, 207, 8, 223, 158, 215, 108, 97, 255, 38, 99, 137, 247, 108, 209, 249, 127, 173, 228, 255, 125, 140, 3, 223, 158, 31, 37, 195, 223, 231, 157, 228, 123, 133, 63, 65, 134, 175, 207, 251, 200, 240, 1, 250, 32, 25, 190, 65, 143, 145, 159, 16, 126, 138, 12, 159, 160, 207, 144, 225, 71, 244, 37, 50, 124, 136, 30, 127, 14, 251, 55, 225, 83, 19, 126, 230, 184, 202, 27, 200, 240, 69, 250, 107, 41, 255, 66, 101, 224, 28, - 157, 127, 172, 53, 188, 229, 28, 253, 140, 119, 201, 189, 46, 97, 28, 248, 34, 157, 37, 195, 119, 233, 59, 24, 31, 127, 130, 97, 159, 3, 125, 208, 113, 234, 111, 65, 174, 52, 248, 93, 138, 149, 122, 168, 114, 139, 193, 31, 54, 248, 211, 70, 252, 207, 25, 252, 117, 131, 143, 25, 252, 132, 193, 207, 25, 233, 188, 104, 200, 255, 219, 224, 13, 231, 102, 188, 217, 224, 243, 12, 190, 192, 224, 55, 27, 60, 100, 240, 91, 13, 30, 49, 120, 194, 224, 105, 131, 47, 51, 120, - 193, 224, 214, 185, 89, 158, 175, 53, 228, 55, 24, 252, 94, 131, 223, 103, 240, 237, 6, 223, 105, 240, 103, 12, 190, 223, 224, 175, 26, 252, 144, 193, 223, 48, 248, 105, 131, 95, 54, 88, 251, 148, 209, 124, 138, 193, 155, 13, 62, 207, 224, 11, 12, 238, 51, 248, 109, 6, 95, 98, 240, 140, 193, 255, 188, 65, 234, 187, 28, 159, 211, 127, 40, 119, 244, 231, 71, 247, 227, 190, 87, 65, 25, 221, 43, 121, 184, 71, 142, 207, 202, 33, 195, 131, 10, 254, 88, 239, 11, 27, - 180, 78, 233, 239, 228, 248, 146, 28, 95, 150, 227, 43, 114, 124, 85, 142, 175, 233, 60, 95, 252, 128, 252, 62, 40, 7, 254, 108, 231, 235, 114, 60, 36, 199, 63, 202, 241, 176, 28, 143, 200, 241, 79, 114, 124, 67, 142, 99, 114, 124, 147, 215, 252, 139, 252, 62, 42, 199, 99, 114, 60, 46, 199, 183, 228, 120, 66, 14, 252, 17, 225, 183, 55, 104, 221, 213, 191, 202, 241, 29, 57, 190, 203, 107, 190, 39, 191, 223, 151, 227, 223, 228, 144, 97, 74, 229, 105, 57, 126, 40, - 199, 51, 27, 176, 22, 96, 89, 81, 108, 135, 177, 252, 54, 107, 158, 99, 251, 242, 245, 175, 47, 123, 117, 245, 23, 234, 214, 156, 235, 215, 93, 127, 222, 90, 112, 188, 150, 19, 74, 28, 117, 10, 255, 100, 109, 121, 65, 176, 40, 113, 45, 107, 239, 228, 212, 200, 238, 73, 203, 154, 176, 182, 89, 197, 191, 239, 46, 61, 111, 252, 217, 122, 233, 249, 236, 127, 198, 243, 167, 15, 204, 90, 83, 85, 75, 253, 81, 120, 254, 132, 72, 71, 170, 211, 123, 70, 171, 211, 49, 146, - 156, 170, 86, 15, 217, 173, 9, 63, 30, 24, 46, 137, 232, 250, 85, 167, 57, 107, 47, 58, 37, 55, 31, 59, 216, 253, 238, 234, 124, 213, 82, 127, 122, 238, 236, 89, 112, 189, 250, 172, 29, 45, 150, 68, 170, 142, 244, 76, 99, 118, 98, 223, 88, 239, 8, 35, 147, 189, 138, 96, 58, 12, 240, 47, 237, 213, 145, 125, 209, 124, 197, 194, 223, 140, 91, 234, 223, 228, 173, 57, 47, 168, 45, 230, 36, 135, 130, 176, 30, 81, 130, 63, 89, 207, 9, 150, 244, 95, 159, 51, - 228, 28, 86, 247, 210, 47, 215, 234, 219, 177, 99, 219, 142, 138, 213, 148, 7, 148, 74, 16, 71, 125, 67, 3, 3, 67, 185, 240, 246, 97, 57, 95, 107, 213, 157, 195, 49, 2, 219, 85, 192, 141, 84, 96, 16, 1, 143, 103, 6, 116, 192, 87, 215, 108, 171, 88, 115, 146, 5, 39, 148, 192, 208, 174, 138, 85, 103, 98, 67, 59, 43, 150, 151, 240, 91, 178, 132, 135, 183, 111, 203, 18, 30, 30, 220, 149, 37, 60, 60, 184, 51, 75, 120, 120, 16, 215, 132, 181, 190, 161, - 157, 67, 3, 138, 172, 237, 131, 86, 108, 207, 137, 96, 135, 92, 180, 191, 221, 156, 106, 57, 126, 223, 240, 192, 78, 57, 45, 101, 200, 63, 172, 151, 162, 136, 164, 204, 156, 120, 220, 179, 231, 37, 157, 157, 219, 229, 116, 228, 52, 173, 90, 28, 74, 228, 65, 220, 220, 143, 251, 118, 236, 220, 62, 172, 18, 153, 105, 227, 110, 3, 59, 229, 214, 177, 219, 116, 250, 118, 12, 15, 13, 177, 252, 60, 201, 34, 81, 110, 191, 93, 138, 64, 106, 228, 94, 39, 150, 23, 58, 43, - 25, 158, 137, 125, 37, 65, 213, 151, 122, 154, 4, 15, 248, 94, 96, 215, 119, 183, 90, 227, 174, 231, 36, 194, 203, 240, 238, 140, 72, 214, 172, 220, 171, 194, 138, 59, 234, 120, 90, 142, 151, 29, 141, 135, 142, 190, 44, 169, 156, 182, 87, 107, 123, 168, 159, 51, 123, 50, 97, 208, 90, 158, 13, 36, 193, 74, 215, 58, 76, 185, 36, 238, 168, 91, 167, 146, 49, 169, 22, 146, 189, 52, 44, 79, 36, 193, 137, 209, 130, 96, 100, 121, 191, 141, 92, 230, 196, 157, 162, 233, - 32, 240, 70, 218, 13, 83, 52, 227, 68, 78, 60, 187, 220, 202, 197, 67, 166, 38, 252, 70, 144, 202, 38, 252, 90, 232, 52, 29, 95, 157, 217, 19, 180, 253, 24, 125, 7, 79, 78, 59, 97, 99, 50, 152, 223, 93, 175, 103, 34, 185, 145, 126, 200, 76, 212, 46, 220, 126, 198, 153, 151, 183, 230, 132, 230, 3, 38, 50, 41, 132, 177, 195, 69, 105, 161, 200, 36, 255, 113, 16, 58, 227, 97, 208, 52, 203, 77, 189, 195, 217, 160, 186, 28, 73, 206, 42, 105, 223, 178, 7, - 93, 236, 129, 86, 118, 195, 124, 127, 147, 136, 246, 122, 193, 156, 237, 141, 218, 177, 157, 201, 146, 44, 100, 146, 170, 227, 215, 199, 150, 164, 80, 74, 68, 151, 185, 241, 130, 249, 162, 120, 14, 53, 169, 243, 26, 60, 206, 62, 219, 101, 37, 26, 175, 38, 191, 214, 200, 114, 236, 160, 35, 149, 96, 210, 91, 119, 156, 57, 224, 250, 49, 170, 122, 73, 191, 95, 236, 202, 19, 201, 225, 56, 180, 107, 49, 42, 188, 47, 213, 3, 5, 55, 109, 199, 11, 233, 249, 73, 169, 215, - 213, 5, 59, 116, 234, 217, 243, 119, 124, 51, 40, 170, 74, 69, 145, 231, 145, 239, 87, 179, 149, 10, 209, 162, 74, 19, 80, 111, 196, 76, 65, 186, 233, 206, 215, 1, 145, 170, 53, 211, 110, 82, 33, 69, 52, 234, 52, 236, 182, 23, 91, 151, 6, 81, 42, 235, 120, 46, 145, 160, 173, 55, 235, 123, 130, 186, 99, 138, 164, 143, 158, 168, 155, 130, 217, 32, 182, 61, 145, 78, 58, 254, 124, 242, 212, 114, 6, 73, 169, 254, 156, 225, 153, 218, 146, 25, 196, 187, 203, 135, - 11, 55, 171, 118, 222, 76, 11, 116, 223, 145, 136, 218, 115, 81, 45, 116, 231, 74, 36, 73, 101, 55, 101, 242, 42, 108, 47, 21, 231, 235, 9, 4, 146, 116, 21, 133, 159, 230, 12, 95, 174, 206, 50, 237, 248, 154, 37, 162, 124, 106, 234, 155, 88, 184, 178, 227, 67, 153, 202, 246, 234, 23, 111, 72, 166, 67, 215, 55, 99, 152, 169, 87, 241, 246, 39, 162, 189, 71, 80, 229, 68, 208, 112, 88, 47, 208, 141, 24, 61, 42, 223, 188, 244, 17, 42, 104, 118, 156, 169, 32, - 235, 55, 19, 81, 218, 101, 38, 2, 163, 3, 233, 20, 101, 97, 179, 207, 208, 210, 131, 85, 62, 126, 18, 236, 184, 202, 108, 220, 74, 50, 94, 205, 154, 27, 5, 108, 90, 12, 37, 143, 204, 160, 106, 64, 245, 144, 33, 179, 237, 80, 164, 27, 72, 26, 195, 154, 63, 98, 97, 68, 24, 90, 115, 237, 70, 148, 72, 228, 249, 101, 52, 168, 27, 145, 150, 52, 92, 207, 179, 92, 127, 14, 253, 42, 37, 94, 59, 90, 176, 14, 201, 216, 49, 56, 148, 200, 22, 218, 141, 88, - 18, 146, 130, 75, 36, 174, 223, 240, 84, 255, 156, 11, 38, 131, 152, 188, 176, 38, 21, 61, 234, 20, 214, 151, 165, 255, 112, 107, 157, 226, 134, 123, 216, 233, 188, 137, 165, 202, 59, 149, 182, 253, 35, 110, 43, 13, 180, 234, 242, 193, 150, 144, 20, 149, 42, 2, 245, 252, 201, 103, 45, 9, 164, 213, 98, 95, 80, 111, 123, 14, 62, 78, 70, 112, 82, 62, 226, 70, 80, 127, 213, 181, 160, 141, 42, 166, 235, 141, 33, 72, 234, 156, 14, 237, 117, 151, 204, 147, 24, 155, - 170, 224, 254, 203, 119, 135, 243, 53, 254, 46, 85, 100, 244, 138, 151, 168, 78, 165, 56, 88, 225, 232, 119, 119, 28, 219, 181, 133, 177, 195, 53, 167, 21, 203, 176, 46, 170, 116, 140, 138, 117, 8, 189, 212, 104, 181, 234, 30, 113, 76, 137, 30, 163, 84, 157, 121, 124, 98, 245, 135, 55, 61, 249, 118, 39, 244, 29, 175, 251, 121, 14, 71, 131, 16, 93, 79, 42, 85, 159, 245, 221, 242, 216, 134, 172, 218, 178, 107, 78, 45, 180, 27, 113, 46, 170, 110, 202, 185, 96, 56, - 25, 28, 218, 62, 56, 19, 120, 94, 176, 228, 132, 157, 39, 103, 93, 25, 249, 200, 71, 191, 42, 245, 223, 55, 83, 58, 24, 200, 203, 150, 215, 56, 234, 74, 235, 119, 154, 198, 25, 213, 87, 205, 217, 81, 122, 163, 105, 219, 71, 213, 209, 1, 20, 101, 250, 1, 79, 68, 204, 191, 81, 118, 104, 182, 106, 170, 164, 131, 210, 132, 248, 101, 72, 11, 125, 204, 95, 114, 195, 192, 111, 170, 239, 171, 142, 149, 27, 225, 165, 194, 72, 154, 181, 220, 33, 92, 114, 234, 29, 55, - 225, 192, 193, 200, 74, 225, 122, 53, 14, 76, 70, 55, 29, 2, 86, 142, 108, 176, 232, 228, 34, 141, 163, 105, 26, 97, 41, 154, 236, 117, 106, 137, 212, 197, 74, 231, 60, 41, 11, 98, 252, 112, 153, 237, 234, 199, 51, 122, 208, 228, 54, 137, 200, 76, 120, 124, 212, 12, 9, 171, 239, 74, 250, 218, 101, 158, 54, 169, 218, 188, 102, 253, 1, 87, 33, 121, 135, 123, 90, 203, 9, 74, 121, 107, 76, 91, 160, 17, 68, 11, 52, 130, 186, 212, 181, 192, 104, 129, 134, 192, - 200, 51, 27, 161, 145, 199, 172, 89, 26, 193, 180, 40, 46, 109, 59, 109, 199, 72, 80, 133, 141, 244, 84, 120, 47, 115, 155, 4, 210, 180, 149, 64, 6, 163, 42, 80, 149, 153, 181, 55, 213, 142, 91, 109, 25, 24, 164, 111, 184, 186, 220, 156, 11, 188, 73, 206, 176, 167, 244, 16, 205, 184, 33, 130, 114, 63, 123, 217, 12, 57, 198, 201, 177, 195, 124, 67, 8, 224, 230, 245, 92, 40, 201, 10, 194, 217, 176, 82, 4, 53, 47, 96, 19, 169, 225, 110, 138, 26, 81, 54, - 213, 80, 2, 87, 62, 198, 13, 221, 189, 120, 145, 227, 232, 87, 213, 92, 164, 168, 137, 10, 160, 40, 144, 25, 151, 130, 22, 62, 206, 13, 133, 152, 132, 18, 154, 1, 75, 55, 108, 242, 210, 182, 159, 93, 172, 230, 175, 32, 117, 11, 85, 171, 57, 128, 87, 108, 188, 130, 44, 156, 116, 170, 73, 145, 103, 1, 185, 84, 5, 102, 228, 86, 10, 170, 35, 230, 215, 182, 58, 194, 241, 21, 67, 198, 32, 48, 145, 24, 227, 164, 130, 72, 85, 231, 130, 84, 11, 140, 55, 169, - 4, 24, 157, 152, 183, 158, 173, 206, 90, 147, 19, 122, 252, 39, 33, 233, 97, 146, 241, 234, 238, 233, 137, 188, 160, 100, 56, 94, 118, 58, 25, 147, 155, 231, 70, 199, 246, 76, 237, 155, 158, 25, 171, 86, 243, 114, 233, 184, 210, 193, 248, 254, 220, 96, 220, 140, 149, 141, 157, 76, 233, 244, 204, 196, 193, 188, 196, 28, 162, 155, 242, 252, 56, 221, 60, 147, 27, 147, 203, 180, 92, 166, 112, 106, 128, 51, 27, 92, 226, 226, 147, 189, 172, 165, 122, 30, 35, 132, 207, 217, - 130, 83, 91, 60, 104, 123, 110, 221, 141, 151, 19, 33, 90, 255, 222, 32, 168, 235, 92, 106, 25, 245, 68, 8, 232, 174, 47, 9, 170, 174, 85, 255, 142, 232, 174, 70, 7, 144, 253, 156, 192, 66, 146, 99, 248, 194, 48, 188, 207, 110, 165, 172, 63, 161, 8, 164, 243, 64, 249, 30, 168, 129, 101, 137, 80, 117, 240, 144, 99, 64, 165, 30, 209, 124, 192, 209, 118, 179, 185, 60, 222, 246, 107, 170, 74, 136, 160, 16, 195, 20, 236, 97, 90, 74, 54, 17, 77, 248, 102, 68, - 169, 246, 251, 219, 77, 117, 42, 170, 170, 207, 144, 8, 117, 229, 34, 164, 121, 148, 106, 139, 215, 178, 79, 62, 163, 102, 56, 9, 166, 154, 182, 130, 202, 9, 2, 221, 22, 179, 24, 170, 153, 41, 210, 51, 23, 61, 53, 73, 131, 19, 186, 16, 85, 17, 99, 160, 152, 241, 84, 163, 17, 57, 113, 42, 145, 241, 167, 201, 185, 179, 173, 32, 52, 113, 60, 213, 225, 40, 81, 164, 70, 54, 42, 128, 185, 73, 54, 205, 210, 162, 100, 2, 165, 56, 206, 170, 148, 4, 164, 178, - 164, 207, 161, 131, 212, 184, 164, 97, 83, 73, 227, 68, 242, 197, 79, 207, 229, 171, 86, 85, 229, 161, 180, 150, 234, 83, 120, 44, 179, 86, 85, 141, 225, 152, 14, 22, 234, 66, 85, 125, 47, 205, 12, 77, 85, 205, 27, 242, 85, 152, 162, 100, 242, 200, 144, 46, 232, 6, 219, 24, 37, 70, 171, 171, 170, 174, 50, 125, 99, 18, 172, 142, 20, 203, 47, 174, 186, 243, 190, 29, 75, 137, 167, 197, 12, 217, 17, 39, 104, 140, 85, 141, 225, 30, 79, 196, 18, 53, 50, 7, - 82, 249, 51, 105, 26, 133, 68, 203, 83, 76, 146, 51, 66, 201, 21, 90, 29, 35, 96, 183, 90, 190, 205, 98, 242, 130, 249, 70, 210, 25, 8, 251, 109, 25, 13, 30, 208, 223, 23, 85, 176, 22, 85, 117, 250, 131, 199, 80, 67, 143, 142, 24, 114, 181, 246, 85, 7, 100, 216, 57, 239, 88, 54, 84, 76, 148, 232, 207, 155, 101, 40, 87, 107, 137, 94, 202, 20, 70, 242, 62, 109, 52, 78, 83, 216, 246, 35, 121, 110, 39, 75, 76, 127, 71, 25, 88, 178, 179, 52, 180, - 30, 183, 51, 101, 45, 237, 76, 90, 75, 99, 123, 222, 242, 168, 92, 200, 157, 48, 111, 218, 10, 165, 76, 84, 89, 89, 205, 5, 203, 57, 236, 212, 218, 18, 35, 153, 216, 213, 236, 184, 6, 41, 71, 181, 86, 104, 187, 40, 165, 82, 49, 150, 15, 226, 222, 39, 45, 183, 46, 61, 145, 106, 8, 53, 244, 175, 150, 237, 217, 97, 83, 74, 162, 229, 137, 168, 30, 88, 77, 153, 184, 88, 126, 16, 187, 141, 101, 171, 142, 242, 209, 89, 235, 56, 227, 7, 82, 76, 190, 100, - 48, 42, 156, 66, 119, 32, 87, 98, 12, 84, 47, 156, 196, 69, 86, 224, 215, 116, 138, 145, 115, 149, 31, 68, 61, 110, 89, 18, 161, 227, 206, 37, 49, 10, 25, 40, 137, 99, 230, 35, 82, 159, 92, 171, 129, 200, 104, 240, 74, 237, 30, 43, 109, 188, 163, 231, 16, 21, 107, 126, 111, 251, 200, 88, 24, 6, 242, 66, 100, 154, 58, 55, 167, 127, 22, 245, 143, 124, 236, 35, 11, 250, 141, 52, 16, 96, 72, 201, 153, 118, 84, 209, 147, 95, 53, 41, 87, 212, 138, 67, - 82, 164, 58, 27, 193, 166, 125, 216, 136, 44, 151, 39, 177, 5, 107, 190, 78, 44, 153, 196, 75, 188, 89, 123, 14, 237, 169, 169, 180, 42, 161, 83, 115, 100, 116, 108, 69, 242, 73, 247, 148, 26, 61, 172, 165, 79, 132, 33, 133, 83, 73, 150, 149, 44, 71, 63, 131, 101, 45, 58, 203, 205, 249, 208, 170, 31, 178, 195, 198, 160, 36, 161, 7, 158, 82, 46, 53, 78, 88, 177, 22, 37, 165, 28, 182, 136, 146, 17, 96, 45, 94, 80, 173, 6, 13, 210, 10, 69, 232, 250, - 146, 17, 169, 88, 106, 148, 139, 53, 170, 243, 15, 236, 159, 184, 124, 112, 219, 54, 172, 66, 216, 50, 105, 172, 85, 146, 150, 173, 126, 140, 211, 146, 186, 47, 131, 95, 125, 105, 131, 145, 26, 242, 184, 158, 17, 169, 81, 215, 141, 187, 193, 14, 161, 193, 96, 50, 144, 109, 232, 97, 108, 67, 141, 136, 27, 186, 237, 54, 80, 213, 229, 39, 150, 1, 189, 252, 168, 38, 103, 36, 57, 239, 196, 45, 183, 94, 209, 21, 34, 255, 32, 77, 167, 89, 195, 192, 8, 191, 152, 237, - 200, 175, 250, 230, 53, 3, 95, 119, 65, 128, 24, 69, 136, 108, 24, 105, 182, 88, 178, 73, 182, 100, 18, 17, 85, 56, 196, 150, 23, 180, 212, 144, 209, 156, 17, 29, 245, 47, 14, 114, 2, 253, 202, 245, 18, 136, 252, 38, 9, 69, 113, 168, 114, 132, 95, 228, 72, 126, 125, 5, 237, 200, 115, 156, 150, 145, 196, 82, 114, 201, 82, 114, 113, 83, 245, 85, 149, 126, 76, 113, 163, 126, 127, 217, 246, 107, 11, 238, 98, 255, 168, 19, 45, 198, 65, 171, 191, 214, 112, 182, - 70, 182, 95, 159, 11, 14, 43, 174, 5, 161, 211, 47, 149, 167, 191, 17, 33, 44, 197, 40, 205, 40, 81, 107, 245, 213, 86, 149, 142, 82, 43, 245, 215, 90, 237, 1, 136, 251, 219, 82, 90, 91, 165, 69, 196, 229, 105, 6, 165, 234, 234, 159, 61, 125, 215, 138, 11, 183, 63, 157, 75, 129, 102, 215, 251, 234, 236, 97, 139, 93, 233, 26, 26, 147, 221, 114, 215, 175, 21, 33, 177, 172, 249, 148, 172, 200, 20, 214, 88, 186, 173, 210, 188, 226, 165, 165, 30, 171, 70, 29, - 250, 253, 21, 12, 14, 214, 80, 150, 210, 195, 45, 173, 95, 97, 170, 212, 178, 210, 44, 46, 148, 117, 89, 8, 43, 46, 112, 173, 96, 66, 193, 85, 189, 87, 252, 224, 125, 125, 70, 190, 219, 177, 178, 8, 89, 143, 46, 57, 77, 42, 232, 49, 57, 237, 61, 219, 235, 53, 155, 91, 121, 118, 148, 159, 235, 228, 39, 75, 29, 179, 147, 242, 89, 79, 199, 124, 172, 56, 9, 236, 62, 251, 89, 205, 100, 172, 108, 10, 216, 107, 18, 218, 117, 18, 214, 49, 177, 237, 152, 105, - 150, 78, 242, 186, 206, 81, 187, 77, 106, 115, 179, 229, 114, 245, 70, 185, 86, 103, 245, 234, 139, 108, 110, 223, 213, 26, 168, 131, 115, 234, 159, 188, 6, 34, 175, 157, 40, 232, 49, 140, 170, 212, 123, 158, 218, 161, 45, 233, 84, 166, 20, 117, 78, 57, 109, 82, 105, 105, 22, 116, 80, 171, 82, 3, 25, 83, 227, 159, 188, 197, 73, 167, 173, 194, 207, 151, 84, 123, 44, 169, 190, 250, 22, 24, 123, 44, 40, 22, 215, 148, 126, 202, 53, 241, 61, 52, 195, 153, 226, 247, - 149, 232, 122, 51, 149, 232, 43, 81, 76, 153, 198, 105, 107, 254, 100, 207, 69, 173, 245, 252, 108, 103, 201, 173, 188, 0, 188, 138, 197, 222, 226, 82, 103, 201, 66, 108, 233, 130, 117, 151, 133, 222, 116, 129, 182, 83, 167, 210, 101, 33, 181, 203, 234, 108, 217, 122, 241, 42, 22, 194, 11, 75, 222, 221, 86, 228, 87, 183, 112, 188, 226, 106, 119, 207, 133, 242, 178, 37, 253, 30, 38, 179, 101, 161, 178, 37, 240, 210, 133, 235, 196, 162, 102, 205, 213, 53, 136, 100, 134, 177, - 158, 21, 214, 76, 208, 92, 228, 78, 151, 114, 203, 22, 60, 215, 190, 64, 221, 115, 245, 216, 88, 13, 205, 45, 36, 231, 172, 150, 251, 219, 81, 216, 239, 250, 53, 175, 93, 119, 250, 61, 119, 110, 81, 234, 94, 191, 187, 125, 231, 112, 191, 68, 195, 20, 105, 74, 205, 156, 23, 86, 185, 254, 156, 44, 55, 27, 171, 174, 233, 2, 107, 193, 50, 160, 176, 42, 92, 178, 250, 220, 125, 77, 57, 93, 8, 78, 151, 117, 179, 69, 93, 99, 229, 184, 124, 225, 59, 93, 30, 206, - 22, 150, 11, 214, 14, 133, 245, 252, 116, 157, 57, 191, 44, 222, 105, 206, 144, 179, 249, 40, 24, 63, 20, 109, 0, 202, 44, 25, 10, 139, 249, 5, 91, 130, 130, 221, 69, 137, 141, 68, 222, 30, 162, 99, 249, 190, 176, 220, 110, 174, 138, 231, 214, 246, 11, 86, 2, 43, 90, 66, 228, 13, 39, 10, 22, 29, 189, 44, 229, 11, 22, 212, 122, 213, 101, 5, 235, 233, 53, 247, 8, 206, 82, 180, 158, 253, 65, 150, 92, 144, 13, 96, 75, 236, 111, 243, 198, 137, 61, 108, - 109, 203, 236, 105, 123, 24, 234, 150, 88, 229, 154, 70, 143, 43, 108, 71, 88, 123, 105, 174, 111, 97, 118, 150, 101, 119, 187, 242, 53, 88, 141, 247, 180, 209, 46, 220, 168, 204, 236, 186, 212, 242, 124, 117, 6, 226, 37, 150, 229, 165, 22, 246, 101, 38, 235, 157, 150, 243, 69, 43, 252, 46, 166, 227, 229, 22, 232, 69, 211, 252, 82, 227, 249, 114, 67, 249, 188, 149, 201, 170, 118, 181, 164, 251, 30, 214, 174, 55, 154, 91, 87, 213, 209, 92, 190, 214, 149, 218, 98, 23, - 76, 149, 75, 172, 186, 87, 99, 175, 253, 19, 182, 202, 46, 179, 193, 94, 209, 42, 187, 96, 132, 221, 211, 206, 188, 103, 119, 83, 90, 150, 57, 235, 247, 220, 30, 152, 53, 215, 12, 236, 161, 89, 207, 186, 97, 164, 23, 172, 96, 66, 94, 98, 126, 222, 105, 67, 94, 180, 50, 239, 89, 120, 157, 183, 202, 54, 8, 173, 189, 156, 230, 188, 117, 45, 166, 52, 185, 164, 148, 86, 101, 162, 223, 97, 219, 191, 194, 182, 181, 181, 61, 116, 35, 146, 49, 198, 58, 60, 173, 78, - 39, 40, 49, 98, 210, 235, 216, 61, 13, 238, 186, 217, 179, 229, 86, 57, 86, 103, 232, 182, 6, 219, 189, 245, 181, 209, 51, 45, 1, 123, 111, 44, 236, 98, 89, 151, 179, 125, 43, 104, 170, 215, 98, 224, 85, 102, 181, 85, 208, 108, 247, 47, 217, 97, 127, 220, 108, 245, 207, 215, 106, 56, 182, 14, 73, 19, 251, 253, 129, 97, 85, 133, 32, 147, 201, 18, 108, 94, 80, 119, 48, 135, 146, 160, 18, 187, 195, 59, 135, 183, 218, 173, 150, 231, 108, 173, 219, 225, 33, 215, - 223, 213, 191, 163, 111, 91, 223, 64, 26, 223, 254, 117, 101, 43, 211, 23, 188, 41, 111, 225, 179, 226, 13, 17, 117, 171, 27, 200, 13, 75, 246, 98, 230, 205, 140, 138, 59, 51, 187, 26, 232, 172, 104, 252, 211, 213, 204, 39, 181, 10, 42, 236, 250, 204, 217, 26, 229, 183, 128, 150, 153, 60, 149, 91, 42, 173, 194, 210, 41, 219, 79, 186, 234, 194, 203, 30, 34, 111, 131, 165, 76, 161, 202, 247, 87, 254, 191, 94, 111, 102, 199, 101, 190, 232, 204, 184, 235, 255, 0, 69, - 83, 60, 165, 164, 182, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -#endif diff --git a/fsw/cfe-core/ut-stubs/ut_fs_stubs.c b/fsw/cfe-core/ut-stubs/ut_fs_stubs.c index 3b553fa42..4324f5bd4 100644 --- a/fsw/cfe-core/ut-stubs/ut_fs_stubs.c +++ b/fsw/cfe-core/ut-stubs/ut_fs_stubs.c @@ -290,6 +290,8 @@ int32 CFE_FS_ExtractFilenameFromPath(const char *OriginalPath, char *FileNameOnl return status; } +#ifndef CFE_OMIT_DEPRECATED_6_7 + /*****************************************************************************/ /** ** \brief CFE_FS_Decompress stub function @@ -375,3 +377,4 @@ int32 CFE_FS_GetUncompressedFile(char *OutputNameBuffer, uint32 OutputNameBuffer return status; } +#endif /* CFE_OMIT_DEPRECATED_6_7 */ From b58ff99db57d690aaef4ca34a99bacf085080804 Mon Sep 17 00:00:00 2001 From: Jacob Hageman Date: Fri, 8 May 2020 16:58:56 -0400 Subject: [PATCH 17/21] Fix #559, Resolve doxygen warnings --- cmake/cfe-common.doxyfile.in | 175 +-------- cmake/osal-common.doxyfile.in | 166 -------- docs/src/cfe_api.dox | 268 +++++++++++++ docs/src/cfe_es.dox | 1 - docs/src/cfe_glossary.dox | 87 +++++ docs/src/cfe_sb.dox | 6 +- docs/src/main.dox | 362 +---------------- fsw/cfe-core/src/es/cfe_es_cds.h | 13 +- fsw/cfe-core/src/inc/cfe_es.h | 78 ++-- fsw/cfe-core/src/inc/cfe_fs.h | 12 +- fsw/cfe-core/src/inc/cfe_sb.h | 429 ++++++++++----------- fsw/cfe-core/src/inc/cfe_sb_msg.h | 6 +- fsw/cfe-core/src/inc/cfe_tbl.h | 38 +- fsw/cfe-core/src/inc/cfe_tbl_events.h | 5 +- fsw/cfe-core/src/inc/cfe_time.h | 6 +- fsw/cfe-core/src/inc/private/cfe_private.h | 13 +- fsw/cfe-core/src/sb/cfe_sb_priv.h | 30 +- fsw/cfe-core/src/tbl/cfe_tbl_internal.h | 48 +-- fsw/cfe-core/src/tbl/cfe_tbl_task.h | 4 +- fsw/cfe-core/src/tbl/cfe_tbl_task_cmds.h | 49 ++- 20 files changed, 707 insertions(+), 1089 deletions(-) create mode 100644 docs/src/cfe_api.dox create mode 100644 docs/src/cfe_glossary.dox diff --git a/cmake/cfe-common.doxyfile.in b/cmake/cfe-common.doxyfile.in index 5fb9965a1..c06c38697 100644 --- a/cmake/cfe-common.doxyfile.in +++ b/cmake/cfe-common.doxyfile.in @@ -2,12 +2,7 @@ # Project related configuration options, shared for all cFE doxygen outputs #--------------------------------------------------------------------------- @INCLUDE_PATH = @MISSION_SOURCE_DIR@ -DOXYFILE_ENCODING = UTF-8 -CREATE_SUBDIRS = NO -OUTPUT_LANGUAGE = English OUTPUT_DIRECTORY = . -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = YES ABBREVIATE_BRIEF = "The $name class " \ "The $name widget " \ "The $name file " \ @@ -19,15 +14,6 @@ ABBREVIATE_BRIEF = "The $name class " \ a \ an \ the -ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = YES -SHORT_NAMES = NO -JAVADOC_AUTOBRIEF = NO -QT_AUTOBRIEF = NO -MULTILINE_CPP_IS_BRIEF = NO -INHERIT_DOCS = YES -SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 8 ALIASES += "event=\xrefitem cfeevents \"Event Message\" \"cFE Event Message Cross Reference\" " \ "cfeescfg=\xrefitem cfeescfg \"Purpose\" \"cFE Executive Services Configuration Parameters\" " \ @@ -50,216 +36,74 @@ ALIASES += "event=\xrefitem cfeevents \"Event Message\" \"cFE Even "cfecmdmnemonic=\xrefitem cfecmdmnems \"Command Mnemonic(s)\" \"cFE Command Mnemonic Cross Reference\" " \ "cfetlmmnemonic=\xrefitem cfetlmmnems \"Telemetry Mnemonic(s)\" \"cFE Telemetry Mnemonic Cross Reference\" " OPTIMIZE_OUTPUT_FOR_C = YES -OPTIMIZE_OUTPUT_JAVA = NO -BUILTIN_STL_SUPPORT = NO -CPP_CLI_SUPPORT = NO -SIP_SUPPORT = NO -DISTRIBUTE_GROUP_DOC = NO -SUBGROUPING = YES -TYPEDEF_HIDES_STRUCT = NO #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = YES EXTRACT_PRIVATE = YES EXTRACT_STATIC = YES -EXTRACT_LOCAL_CLASSES = YES -EXTRACT_LOCAL_METHODS = NO -EXTRACT_ANON_NSPACES = NO -HIDE_UNDOC_MEMBERS = NO -HIDE_UNDOC_CLASSES = NO -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO -INTERNAL_DOCS = NO CASE_SENSE_NAMES = NO -HIDE_SCOPE_NAMES = NO -SHOW_INCLUDE_FILES = YES -INLINE_INFO = YES -SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = NO -SORT_BY_SCOPE_NAME = NO GENERATE_TODOLIST = NO -GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 -SHOW_USED_FILES = YES -FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = YES -WARN_FORMAT = "$file:$line: $text " WARN_LOGFILE = @CMAKE_BINARY_DIR@/doc/warnings.log #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- -INPUT_ENCODING = UTF-8 -STRIP_FROM_PATH = @MISSION_SOURCE_DIR@ +STRIP_FROM_PATH = @MISSION_SOURCE_DIR@ # Always include a standard set of CFE documentation in the input set # This is applicable to both users guide and detail design outputs -IMAGE_PATH += @MISSION_SOURCE_DIR@/cfe/docs/src -INPUT += @MISSION_SOURCE_DIR@/cfe/docs/src/cfe_es.dox -INPUT += @MISSION_SOURCE_DIR@/cfe/docs/src/cfe_evs.dox -INPUT += @MISSION_SOURCE_DIR@/cfe/docs/src/cfe_sb.dox -INPUT += @MISSION_SOURCE_DIR@/cfe/docs/src/cfe_tbl.dox -INPUT += @MISSION_SOURCE_DIR@/cfe/docs/src/cfe_time.dox +IMAGE_PATH += @MISSION_SOURCE_DIR@/cfe/docs/src +INPUT += @MISSION_SOURCE_DIR@/cfe/docs/src/cfe_glossary.dox +INPUT += @MISSION_SOURCE_DIR@/cfe/docs/src/cfe_api.dox +INPUT += @MISSION_SOURCE_DIR@/cfe/docs/src/cfe_es.dox +INPUT += @MISSION_SOURCE_DIR@/cfe/docs/src/cfe_evs.dox +INPUT += @MISSION_SOURCE_DIR@/cfe/docs/src/cfe_sb.dox +INPUT += @MISSION_SOURCE_DIR@/cfe/docs/src/cfe_tbl.dox +INPUT += @MISSION_SOURCE_DIR@/cfe/docs/src/cfe_time.dox INPUT += @MISSION_SOURCE_DIR@/cfe/docs/src/cfe_xref.dox FILE_PATTERNS = *.c *.cpp *.cc *.C *.h *.hh *.hpp *.H *.dox *.md RECURSIVE = YES -EXCLUDE = -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXCLUDE_SYMBOLS = -EXAMPLE_PATH = EXAMPLE_PATTERNS = * -EXAMPLE_RECURSIVE = NO -INPUT_FILTER = -FILTER_PATTERNS = -FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- SOURCE_BROWSER = YES -INLINE_SOURCES = NO -STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = YES REFERENCES_RELATION = YES -REFERENCES_LINK_SOURCE = YES -USE_HTAGS = NO -VERBATIM_HEADERS = YES -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = YES -COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = html -HTML_FILE_EXTENSION = .html -HTML_HEADER = -HTML_FOOTER = -HTML_STYLESHEET = -GENERATE_HTMLHELP = NO -HTML_DYNAMIC_SECTIONS = NO -CHM_FILE = -HHC_LOCATION = -GENERATE_CHI = NO -BINARY_TOC = NO -TOC_EXPAND = NO -DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = NO -TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- GENERATE_LATEX = NO -LATEX_OUTPUT = latex LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = YES PAPER_TYPE = letter -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = YES -USE_PDFLATEX = YES -LATEX_BATCHMODE = NO -LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf COMPACT_RTF = YES -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = NO -XML_OUTPUT = xml -XML_PROGRAMLISTING = YES -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- -GENERATE_AUTOGEN_DEF = NO -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- -GENERATE_PERLMOD = NO -PERLMOD_LATEX = NO -PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = NO -MSCGEN_PATH = -HIDE_UNDOC_RELATIONS = YES HAVE_DOT = YES CLASS_GRAPH = NO COLLABORATION_GRAPH = NO -GROUP_GRAPHS = YES -UML_LOOK = NO -TEMPLATE_RELATIONS = NO INCLUDE_GRAPH = NO INCLUDED_BY_GRAPH = NO CALL_GRAPH = YES -CALLER_GRAPH = NO GRAPHICAL_HIERARCHY = NO -DIRECTORY_GRAPH = YES -DOT_IMAGE_FORMAT = png -DOT_PATH = -DOTFILE_DIRS = -DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 1000 -DOT_TRANSPARENT = NO -DOT_MULTI_TARGETS = NO -GENERATE_LEGEND = YES -DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = NO - #--------------------------------------------------------------------------- # CFE mnemonic mappings #--------------------------------------------------------------------------- @@ -273,4 +117,3 @@ SEARCHENGINE = NO @INCLUDE = @MISSION_SOURCE_DIR@/cfe/docs/src/mnem_maps/cfe_evs_tlm_mnem_map @INCLUDE = @MISSION_SOURCE_DIR@/cfe/docs/src/mnem_maps/cfe_sb_cmd_mnem_map @INCLUDE = @MISSION_SOURCE_DIR@/cfe/docs/src/mnem_maps/cfe_sb_tlm_mnem_map - diff --git a/cmake/osal-common.doxyfile.in b/cmake/osal-common.doxyfile.in index d6127578f..79cc593f8 100644 --- a/cmake/osal-common.doxyfile.in +++ b/cmake/osal-common.doxyfile.in @@ -2,12 +2,7 @@ # Project related configuration options, shared for all cFE doxygen outputs #--------------------------------------------------------------------------- @INCLUDE_PATH = @MISSION_SOURCE_DIR@ -DOXYFILE_ENCODING = UTF-8 -CREATE_SUBDIRS = NO -OUTPUT_LANGUAGE = English OUTPUT_DIRECTORY = . -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = YES ABBREVIATE_BRIEF = "The $name class " \ "The $name widget " \ "The $name file " \ @@ -19,225 +14,64 @@ ABBREVIATE_BRIEF = "The $name class " \ a \ an \ the -ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = YES -SHORT_NAMES = NO -JAVADOC_AUTOBRIEF = NO -QT_AUTOBRIEF = NO -MULTILINE_CPP_IS_BRIEF = NO -INHERIT_DOCS = YES -SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 8 OPTIMIZE_OUTPUT_FOR_C = YES -OPTIMIZE_OUTPUT_JAVA = NO -BUILTIN_STL_SUPPORT = NO -CPP_CLI_SUPPORT = NO -SIP_SUPPORT = NO -DISTRIBUTE_GROUP_DOC = NO -SUBGROUPING = YES -TYPEDEF_HIDES_STRUCT = NO #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = YES EXTRACT_PRIVATE = YES EXTRACT_STATIC = YES -EXTRACT_LOCAL_CLASSES = YES -EXTRACT_LOCAL_METHODS = NO -EXTRACT_ANON_NSPACES = NO -HIDE_UNDOC_MEMBERS = NO -HIDE_UNDOC_CLASSES = NO -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO -INTERNAL_DOCS = NO CASE_SENSE_NAMES = NO -HIDE_SCOPE_NAMES = NO -SHOW_INCLUDE_FILES = YES -INLINE_INFO = YES -SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = NO -SORT_BY_SCOPE_NAME = NO GENERATE_TODOLIST = NO -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 -SHOW_USED_FILES = YES -FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = YES -WARN_FORMAT = "$file:$line: $text " WARN_LOGFILE = @CMAKE_BINARY_DIR@/doc/warnings.log #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- -INPUT_ENCODING = UTF-8 STRIP_FROM_PATH = @MISSION_SOURCE_DIR@ # Always include a standard set of CFE documentation in the input set # This is applicable to both users guide and detail design outputs -#IMAGE_PATH += INPUT += @MISSION_SOURCE_DIR@/cfe/docs/src/osal_fs.dox INPUT += @MISSION_SOURCE_DIR@/cfe/docs/src/osal_timer.dox FILE_PATTERNS = *.c *.cpp *.cc *.C *.h *.hh *.hpp *.H *.dox *.md RECURSIVE = YES -EXCLUDE = -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXCLUDE_SYMBOLS = -EXAMPLE_PATH = EXAMPLE_PATTERNS = * -EXAMPLE_RECURSIVE = NO -INPUT_FILTER = -FILTER_PATTERNS = -FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- SOURCE_BROWSER = YES -INLINE_SOURCES = NO -STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = YES REFERENCES_RELATION = YES -REFERENCES_LINK_SOURCE = YES -USE_HTAGS = NO -VERBATIM_HEADERS = YES -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = YES -COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = html -HTML_FILE_EXTENSION = .html -HTML_HEADER = -HTML_FOOTER = -HTML_STYLESHEET = -GENERATE_HTMLHELP = NO -HTML_DYNAMIC_SECTIONS = NO -CHM_FILE = -HHC_LOCATION = -GENERATE_CHI = NO -BINARY_TOC = NO -TOC_EXPAND = NO -DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = NO -TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- GENERATE_LATEX = NO -LATEX_OUTPUT = latex LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = YES PAPER_TYPE = letter -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = YES -USE_PDFLATEX = YES -LATEX_BATCHMODE = NO -LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf COMPACT_RTF = YES -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = NO -XML_OUTPUT = xml -XML_PROGRAMLISTING = YES -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- -GENERATE_AUTOGEN_DEF = NO -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- -GENERATE_PERLMOD = NO -PERLMOD_LATEX = NO -PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = NO -MSCGEN_PATH = -HIDE_UNDOC_RELATIONS = YES HAVE_DOT = YES CLASS_GRAPH = NO COLLABORATION_GRAPH = NO -GROUP_GRAPHS = YES -UML_LOOK = NO -TEMPLATE_RELATIONS = NO INCLUDE_GRAPH = NO INCLUDED_BY_GRAPH = NO CALL_GRAPH = YES -CALLER_GRAPH = NO GRAPHICAL_HIERARCHY = NO -DIRECTORY_GRAPH = YES -DOT_IMAGE_FORMAT = png -DOT_PATH = -DOTFILE_DIRS = -DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 1000 -DOT_TRANSPARENT = NO -DOT_MULTI_TARGETS = NO -GENERATE_LEGEND = YES -DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- SEARCHENGINE = NO - -#--------------------------------------------------------------------------- -# OSAL mnemonic mappings -#--------------------------------------------------------------------------- -#@INCLUDE = - diff --git a/docs/src/cfe_api.dox b/docs/src/cfe_api.dox new file mode 100644 index 000000000..7a5113cb7 --- /dev/null +++ b/docs/src/cfe_api.dox @@ -0,0 +1,268 @@ +/** + \page cfeapi cFE Application Programmer's Interface (API) Reference +

Executive Services API

+
    +
  • \ref CFEAPIESEntryExit +
      +
    • #CFE_ES_Main - \copybrief CFE_ES_Main +
    • #CFE_ES_ResetCFE - \copybrief CFE_ES_ResetCFE +
    +
  • \ref CFEAPIESAppControl +
      +
    • #CFE_ES_RestartApp - \copybrief CFE_ES_RestartApp +
    • #CFE_ES_ReloadApp - \copybrief CFE_ES_ReloadApp +
    • #CFE_ES_DeleteApp - \copybrief CFE_ES_DeleteApp +
    +
  • \ref CFEAPIESAppBehavior +
      +
    • #CFE_ES_RegisterApp - \copybrief CFE_ES_RegisterApp +
    • #CFE_ES_RunLoop - \copybrief CFE_ES_RunLoop +
    • #CFE_ES_WaitForStartupSync - \copybrief CFE_ES_WaitForStartupSync +
    • #CFE_ES_WaitForSystemState - \copybrief CFE_ES_WaitForSystemState +
    • #CFE_ES_IncrementTaskCounter - \copybrief CFE_ES_IncrementTaskCounter +
    • #CFE_ES_ExitApp - \copybrief CFE_ES_ExitApp +
    +
  • \ref CFEAPIESInfo +
      +
    • #CFE_ES_GetResetType - \copybrief CFE_ES_GetResetType +
    • #CFE_ES_GetAppID - \copybrief CFE_ES_GetAppID +
    • #CFE_ES_GetAppIDByName - \copybrief CFE_ES_GetAppIDByName +
    • #CFE_ES_GetAppName - \copybrief CFE_ES_GetAppName +
    • #CFE_ES_GetAppInfo - \copybrief CFE_ES_GetAppInfo +
    • #CFE_ES_GetTaskInfo - \copybrief CFE_ES_GetTaskInfo +
    +
  • \ref CFEAPIESChildTask +
      +
    • #CFE_ES_RegisterChildTask - \copybrief CFE_ES_RegisterChildTask +
    • #CFE_ES_CreateChildTask - \copybrief CFE_ES_CreateChildTask +
    • #CFE_ES_DeleteChildTask - \copybrief CFE_ES_DeleteChildTask +
    • #CFE_ES_ExitChildTask - \copybrief CFE_ES_ExitChildTask +
    +
  • \ref CFEAPIESCritData +
      +
    • #CFE_ES_RegisterCDS - \copybrief CFE_ES_RegisterCDS +
    • #CFE_ES_CopyToCDS - \copybrief CFE_ES_CopyToCDS +
    • #CFE_ES_RestoreFromCDS - \copybrief CFE_ES_RestoreFromCDS +
    +
  • \ref CFEAPIESMemManage +
      +
    • #CFE_ES_PoolCreate - \copybrief CFE_ES_PoolCreate +
    • #CFE_ES_PoolCreateEx - \copybrief CFE_ES_PoolCreateEx +
    • #CFE_ES_PoolCreateNoSem - \copybrief CFE_ES_PoolCreateNoSem +
    • #CFE_ES_GetPoolBuf - \copybrief CFE_ES_GetPoolBuf +
    • #CFE_ES_PutPoolBuf - \copybrief CFE_ES_PutPoolBuf +
    • #CFE_ES_GetMemPoolStats - \copybrief CFE_ES_GetMemPoolStats +
    • #CFE_ES_GetPoolBufInfo - \copybrief CFE_ES_GetPoolBufInfo +
    +
  • \ref CFEAPIESPerfMon +
      +
    • #CFE_ES_PerfLogEntry - \copybrief CFE_ES_PerfLogEntry +
    • #CFE_ES_PerfLogExit - \copybrief CFE_ES_PerfLogExit +
    • #CFE_ES_PerfLogAdd - \copybrief CFE_ES_PerfLogAdd +
    +
  • \ref CFEAPIESGenCount +
      +
    • #CFE_ES_RegisterGenCounter - \copybrief CFE_ES_RegisterGenCounter +
    • #CFE_ES_DeleteGenCounter - \copybrief CFE_ES_DeleteGenCounter +
    • #CFE_ES_IncrementGenCounter - \copybrief CFE_ES_IncrementGenCounter +
    • #CFE_ES_SetGenCount - \copybrief CFE_ES_SetGenCount +
    • #CFE_ES_GetGenCount - \copybrief CFE_ES_GetGenCount +
    • #CFE_ES_GetGenCounterIDByName - \copybrief CFE_ES_GetGenCounterIDByName +
    +
  • \ref CFEAPIESMisc +
      +
    • #CFE_ES_CalculateCRC - \copybrief CFE_ES_CalculateCRC +
    • #CFE_ES_WriteToSysLog - \copybrief CFE_ES_WriteToSysLog +
    • #CFE_ES_ProcessAsyncEvent - \copybrief CFE_ES_ProcessAsyncEvent +
    +
+ +

Events Services API

+
    +
  • \ref CFEAPIEVSReg +
      +
    • #CFE_EVS_Register - \copybrief CFE_EVS_Register +
    • #CFE_EVS_Unregister - \copybrief CFE_EVS_Unregister +
    +
  • \ref CFEAPIEVSSend +
      +
    • #CFE_EVS_SendEvent - \copybrief CFE_EVS_SendEvent +
    • #CFE_EVS_SendEventWithAppID - \copybrief CFE_EVS_SendEventWithAppID +
    • #CFE_EVS_SendTimedEvent - \copybrief CFE_EVS_SendTimedEvent +
    +
  • \ref CFEAPIEVSResetFilter +
      +
    • #CFE_EVS_ResetFilter - \copybrief CFE_EVS_ResetFilter +
    • #CFE_EVS_ResetAllFilters - \copybrief CFE_EVS_ResetAllFilters +
    +
+ +

File Services API

+
    +
  • \ref CFEAPIFSHeader +
      +
    • #CFE_FS_ReadHeader - \copybrief CFE_FS_ReadHeader +
    • #CFE_FS_InitHeader - \copybrief CFE_FS_InitHeader +
    • #CFE_FS_WriteHeader - \copybrief CFE_FS_WriteHeader +
    • #CFE_FS_SetTimestamp - \copybrief CFE_FS_SetTimestamp +
    +
  • \ref CFEAPIFSCompress +
      +
    • #CFE_FS_IsGzFile - \copybrief CFE_FS_IsGzFile +
    • #CFE_FS_Decompress - \copybrief CFE_FS_Decompress +
    • #CFE_FS_GetUncompressedFile - \copybrief CFE_FS_GetUncompressedFile +
    +
  • \ref CFEAPIFSUtil +
      +
    • #CFE_FS_ExtractFilenameFromPath - \copybrief CFE_FS_ExtractFilenameFromPath +
    +
+ +

Software Bus API

+
    +
  • \ref CFEAPISBPipe +
      +
    • #CFE_SB_CreatePipe - \copybrief CFE_SB_CreatePipe +
    • #CFE_SB_DeletePipe - \copybrief CFE_SB_DeletePipe +
    • #CFE_SB_SetPipeOpts - \copybrief CFE_SB_SetPipeOpts +
    • #CFE_SB_GetPipeOpts - \copybrief CFE_SB_GetPipeOpts +
    • #CFE_SB_GetPipeName - \copybrief CFE_SB_GetPipeName +
    • #CFE_SB_GetPipeIdByName - \copybrief CFE_SB_GetPipeIdByName +
    +
  • \ref CFEAPISBSubscription +
      +
    • #CFE_SB_Subscribe - \copybrief CFE_SB_Subscribe +
    • #CFE_SB_SubscribeEx - \copybrief CFE_SB_SubscribeEx +
    • #CFE_SB_SubscribeLocal - \copybrief CFE_SB_SubscribeLocal +
    • #CFE_SB_Unsubscribe - \copybrief CFE_SB_Unsubscribe +
    • #CFE_SB_UnsubscribeLocal - \copybrief CFE_SB_UnsubscribeLocal +
    +
  • \ref CFEAPISBMessage +
      +
    • #CFE_SB_SendMsg - \copybrief CFE_SB_SendMsg +
    • #CFE_SB_PassMsg - \copybrief CFE_SB_PassMsg +
    • #CFE_SB_RcvMsg - \copybrief CFE_SB_RcvMsg +
    +
  • \ref CFEAPISBZeroCopy +
      +
    • #CFE_SB_ZeroCopyGetPtr - \copybrief CFE_SB_ZeroCopyGetPtr +
    • #CFE_SB_ZeroCopyReleasePtr - \copybrief CFE_SB_ZeroCopyReleasePtr +
    • #CFE_SB_ZeroCopySend - \copybrief CFE_SB_ZeroCopySend +
    • #CFE_SB_ZeroCopyPass - \copybrief CFE_SB_ZeroCopyPass +
    +
  • \ref CFEAPISBSetMessage +
      +
    • #CFE_SB_InitMsg - \copybrief CFE_SB_InitMsg +
    • #CFE_SB_SetMsgId - \copybrief CFE_SB_SetMsgId +
    • #CFE_SB_SetUserDataLength - \copybrief CFE_SB_SetUserDataLength +
    • #CFE_SB_SetTotalMsgLength - \copybrief CFE_SB_SetTotalMsgLength +
    • #CFE_SB_SetMsgTime - \copybrief CFE_SB_SetMsgTime +
    • #CFE_SB_TimeStampMsg - \copybrief CFE_SB_TimeStampMsg +
    • #CFE_SB_SetCmdCode - \copybrief CFE_SB_SetCmdCode +
    • #CFE_SB_MessageStringSet - \copybrief CFE_SB_MessageStringSet +
    +
  • \ref CFEAPIGetMessage +
      +
    • #CFE_SB_GetUserData - \copybrief CFE_SB_GetUserData +
    • #CFE_SB_GetMsgId - \copybrief CFE_SB_GetMsgId +
    • #CFE_SB_GetUserDataLength - \copybrief CFE_SB_GetUserDataLength +
    • #CFE_SB_GetTotalMsgLength - \copybrief CFE_SB_GetTotalMsgLength +
    • #CFE_SB_GetMsgTime - \copybrief CFE_SB_GetMsgTime +
    • #CFE_SB_GetCmdCode - \copybrief CFE_SB_GetCmdCode +
    • #CFE_SB_GetLastSenderId - \copybrief CFE_SB_GetLastSenderId +
    • #CFE_SB_MessageStringGet - \copybrief CFE_SB_MessageStringGet +
    +
  • \ref CFEAPISBChecksum +
      +
    • #CFE_SB_GenerateChecksum - \copybrief CFE_SB_GenerateChecksum +
    • #CFE_SB_GetChecksum - \copybrief CFE_SB_GetChecksum +
    • #CFE_SB_ValidateChecksum - \copybrief CFE_SB_ValidateChecksum +
    +
  • \ref CFEAPISBMessageID +
      +
    • #CFE_SB_MsgId_Equal - \copybrief CFE_SB_MsgId_Equal +
    • #CFE_SB_MsgIdToValue - \copybrief CFE_SB_MsgIdToValue +
    • #CFE_SB_ValueToMsgId - \copybrief CFE_SB_ValueToMsgId +
    +
+ +

Table Services API

+
    +
  • \ref CFEAPITBLRegistration +
      +
    • #CFE_TBL_Register - \copybrief CFE_TBL_Register +
    • #CFE_TBL_Share - \copybrief CFE_TBL_Share +
    • #CFE_TBL_Unregister - \copybrief CFE_TBL_Unregister +
    +
  • \ref CFEAPITBLManage +
      +
    • #CFE_TBL_Load - \copybrief CFE_TBL_Load +
    • #CFE_TBL_Update - \copybrief CFE_TBL_Update +
    • #CFE_TBL_Validate - \copybrief CFE_TBL_Validate +
    • #CFE_TBL_Manage - \copybrief CFE_TBL_Manage +
    • #CFE_TBL_DumpToBuffer - \copybrief CFE_TBL_DumpToBuffer +
    • #CFE_TBL_Modified - \copybrief CFE_TBL_Modified +
    +
  • \ref CFEAPITBLAccess +
      +
    • #CFE_TBL_GetAddress - \copybrief CFE_TBL_GetAddress +
    • #CFE_TBL_GetAddresses - \copybrief CFE_TBL_GetAddresses +
    • #CFE_TBL_ReleaseAddress - \copybrief CFE_TBL_ReleaseAddress +
    • #CFE_TBL_ReleaseAddresses - \copybrief CFE_TBL_ReleaseAddresses +
    +
  • \ref CFEAPITBLInfo +
      +
    • #CFE_TBL_GetStatus - \copybrief CFE_TBL_GetStatus +
    • #CFE_TBL_GetInfo - \copybrief CFE_TBL_GetInfo +
    • #CFE_TBL_NotifyByMessage - \copybrief CFE_TBL_NotifyByMessage +
    +
+ +

Time Services API

+
    +
  • \ref CFEAPITIMEGetCurrent +
      +
    • #CFE_TIME_GetTime - \copybrief CFE_TIME_GetTime +
    • #CFE_TIME_GetTAI - \copybrief CFE_TIME_GetTAI +
    • #CFE_TIME_GetUTC - \copybrief CFE_TIME_GetUTC +
    • #CFE_TIME_GetMET - \copybrief CFE_TIME_GetMET +
    • #CFE_TIME_GetMETseconds - \copybrief CFE_TIME_GetMETseconds +
    • #CFE_TIME_GetMETsubsecs - \copybrief CFE_TIME_GetMETsubsecs +
    +
  • \ref CFEAPITIMEGetInfo +
      +
    • #CFE_TIME_GetSTCF - \copybrief CFE_TIME_GetSTCF +
    • #CFE_TIME_GetLeapSeconds - \copybrief CFE_TIME_GetLeapSeconds +
    • #CFE_TIME_GetClockState - \copybrief CFE_TIME_GetClockState +
    • #CFE_TIME_GetClockInfo - \copybrief CFE_TIME_GetClockInfo +
    +
  • \ref CFEAPITIMEArithmetic +
      +
    • #CFE_TIME_Add - \copybrief CFE_TIME_Add +
    • #CFE_TIME_Subtract - \copybrief CFE_TIME_Subtract +
    • #CFE_TIME_Compare - \copybrief CFE_TIME_Compare +
    +
  • \ref CFEAPITIMEConvert +
      +
    • #CFE_TIME_MET2SCTime - \copybrief CFE_TIME_MET2SCTime +
    • #CFE_TIME_Sub2MicroSecs - \copybrief CFE_TIME_Sub2MicroSecs +
    • #CFE_TIME_Micro2SubSecs - \copybrief CFE_TIME_Micro2SubSecs +
    • #CFE_TIME_CFE2FSSeconds - \copybrief CFE_TIME_CFE2FSSeconds +
    • #CFE_TIME_FS2CFESeconds - \copybrief CFE_TIME_FS2CFESeconds +
    +
  • \ref CFEAPITIMEExternSource +
      +
    • #CFE_TIME_ExternalTone - \copybrief CFE_TIME_ExternalTone +
    • #CFE_TIME_ExternalMET - \copybrief CFE_TIME_ExternalMET +
    • #CFE_TIME_ExternalGPS - \copybrief CFE_TIME_ExternalGPS +
    • #CFE_TIME_ExternalTime - \copybrief CFE_TIME_ExternalTime +
    • #CFE_TIME_RegisterSynchCallback - \copybrief CFE_TIME_RegisterSynchCallback +
    • #CFE_TIME_UnregisterSynchCallback - \copybrief CFE_TIME_UnregisterSynchCallback +
    +
  • \ref CFEAPITIMEMisc +
      +
    • #CFE_TIME_Print - \copybrief CFE_TIME_Print +
    • #CFE_TIME_Local1HzISR - \copybrief CFE_TIME_Local1HzISR +
    +
+**/ diff --git a/docs/src/cfe_es.dox b/docs/src/cfe_es.dox index 1376969eb..a2e817a8a 100644 --- a/docs/src/cfe_es.dox +++ b/docs/src/cfe_es.dox @@ -849,4 +849,3 @@ The following are configuration parameters used to configure the cFE Executive Services either for each platform or for a mission as a whole. **/ - diff --git a/docs/src/cfe_glossary.dox b/docs/src/cfe_glossary.dox new file mode 100644 index 000000000..2461a3785 --- /dev/null +++ b/docs/src/cfe_glossary.dox @@ -0,0 +1,87 @@ +/** + \page cfeglossary Glossary of Terms + + + + + + + + + + + + + + + + + + + +
Term + Definition +
\anchor cfeadg_application Application (or App) + A set of data and functions that is treated as a single entity + by the cFE. cFE resources are allocated on a per-Application + basis. Applications are made up of a Main Task and zero or + more Child Tasks. +
\anchor cfeadg_applicationid Application ID + A processor unique reference to an Application.
+ NOTE: This is different from a CCSDS Application ID which is + referred to as an "APID." +
\anchor cfeadg_api Application Programmer's Interface (API) + A set of routines, protocols, and tools for building software + applications +
\anchor cfeadg_psp Platform Support Package (PSP) + A collection of user-provided facilities that interface an OS + and the cFE with a specific hardware platform. The PSP is + responsible for hardware initialization. +
\anchor cfeadg_childtask Child Task + A separate thread of execution that is spawned by an + Application's Main Task. +
\anchor cfeadg_command Command + A Software Bus Message defined by the receiving Application. + Commands can originate from other onboard Applications or + from the ground. +
\anchor cfeadg_cfe Core Flight Executive (cFE) + A runtime environment and a set of services for hosting FSW + Applications +
\anchor cfeadg_cds Critical Data Store (CDS) + A collection of data that is not modified by the OS or + cFE following a Processor Reset. +
\anchor cfeadg_crc Cyclic Redundancy Check + A polynomial based method for checking that a data set + has remained unchanged from one time period to another. +
\anchor cfeadg_developer Developer + Anyone who is coding a cFE Application. +
\anchor cfeadg_eventdata Event Data + Data describing an Event that is supplied to the cFE + Event Service. The cFE includes this data in an + \ref cfeadg_eventmessage "Event Message". +
\anchor cfeadg_eventfilter Event Filter + A numeric value (bit mask) used to determine how + frequently to output an application Event Message + defined by its \ref cfeadg_eventid "Event ID". +
\anchor cfeadg_eventformatmode Event Format Mode + Defines the Event Message Format downlink option: short or long. + The short format is used when there is limited telemetry bandwidth + and is binary. The long format is in ASCII and is used for + logging to a Local Event Log and to an Event Message Port. +
\anchor cfeadg_eventid Event ID + A numeric literal used to uniquely name an Application event. +
\anchor cfeadg_eventtype Event Type + A numeric literal used to identify the type of an Application event. + An event type may be #CFE_EVS_DEBUG, #CFE_EVS_INFORMATION, + #CFE_EVS_ERROR, or #CFE_EVS_CRITICAL. +
\anchor cfeadg_eventmessage Event Message + A data item used to notify the user and/or an external + \ref cfeadg_application "Application" of a significant event. + Event Messages include a time-stamp of when the message was + generated, a processor unique identifier, an + \ref cfeadg_applicationid "Application ID", the + \ref cfeadg_eventtype "Event Type" (DEBUG,INFO,ERROR or CRITICAL), + and \ref cfeadg_eventdata "Event Data". An Event Message can + either be real-time or playback from a Local Event Log. +
+**/ diff --git a/docs/src/cfe_sb.dox b/docs/src/cfe_sb.dox index 7469d1f2c..6a89c305f 100644 --- a/docs/src/cfe_sb.dox +++ b/docs/src/cfe_sb.dox @@ -6,8 +6,7 @@ by sending command and telemetry messages. The software bus provides an application programming interface (API) to other tasks for sending and receiving messages. This API is independent of the underlying operating system so that tasks can use - the same interface regardless of which processor they reside on. Refer to the - \ref cfeapi for detailed information about the API functions. + the same interface regardless of which processor they reside on. Refer to the \ref cfeapi for detailed information about the API functions. The software bus is used internally by the flight software, and normally does not require attention from the ground. However, because of the scalability and the @@ -533,7 +532,7 @@ can get confusing. How can I be sure that the correct address is given for this parameter.   - Typically a caller declares a ptr of type #CFE_SB_Msg_t (i.e. CFE_SB_Msg_t *Ptr) + Typically a caller declares a ptr of type CFE_SB_Msg_t (i.e. CFE_SB_Msg_t *Ptr) then gives the address of that pointer (&Ptr) as this parameter. After a successful call to #CFE_SB_RcvMsg, Ptr will point to the first byte of the software bus message header. This should be used as a read-only pointer. In systems with an MMU, writes @@ -602,4 +601,3 @@ ** The following are configuration parameters used to configure the cFE Software Bus ** either for each platform or for a mission as a whole. **/ - diff --git a/docs/src/main.dox b/docs/src/main.dox index d2cdf1efc..068aac3cc 100644 --- a/docs/src/main.dox +++ b/docs/src/main.dox @@ -9,7 +9,7 @@
  • \subpage cfeversion
  • \subpage cfedependencies
  • \subpage cfeacronyms -
  • \subpage cfeglossary +
  • \ref cfeglossary
  • Executive Services (ES)
      @@ -54,7 +54,7 @@
    • \subpage cfeevents
    • \subpage cfecmdmnems
    • \subpage cfetlmmnems -
    • \subpage cfeapi +
    • \ref cfeapi
    **/ @@ -308,361 +308,3 @@ Coordinated Universal Time **/ - -/** - \page cfeglossary Glossary of Terms - - - - - - - - - - - - - - - - - - - -
    Term - Definition -
    \anchor cfeadg_application Application (or App) - A set of data and functions that is treated as a single entity - by the cFE. cFE resources are allocated on a per-Application - basis. Applications are made up of a Main Task and zero or - more Child Tasks. -
    \anchor cfeadg_applicationid Application ID - A processor unique reference to an Application.
    - NOTE: This is different from a CCSDS Application ID which is - referred to as an "APID." -
    \anchor cfeadg_api Application Programmer's Interface (API) - A set of routines, protocols, and tools for building software - applications -
    \anchor cfeadg_psp Platform Support Package (PSP) - A collection of user-provided facilities that interface an OS - and the cFE with a specific hardware platform. The PSP is - responsible for hardware initialization. -
    \anchor cfeadg_childtask Child Task - A separate thread of execution that is spawned by an - Application's Main Task. -
    \anchor cfeadg_command Command - A Software Bus Message defined by the receiving Application. - Commands can originate from other onboard Applications or - from the ground. -
    \anchor cfeadg_cfe Core Flight Executive (cFE) - A runtime environment and a set of services for hosting FSW - Applications -
    \anchor cfeadg_cds Critical Data Store (CDS) - A collection of data that is not modified by the OS or - cFE following a Processor Reset. -
    \anchor cfeadg_crc Cyclic Redundancy Check - A polynomial based method for checking that a data set - has remained unchanged from one time period to another. -
    \anchor cfeadg_developer Developer - Anyone who is coding a cFE Application. -
    \anchor cfeadg_eventdata Event Data - Data describing an Event that is supplied to the cFE - Event Service. The cFE includes this data in an - \ref cfeadg_eventmessage "Event Message". -
    \anchor cfeadg_eventfilter Event Filter - A numeric value (bit mask) used to determine how - frequently to output an application Event Message - defined by its \ref cfeadg_eventid "Event ID". -
    \anchor cfeadg_eventformatmode Event Format Mode - Defines the Event Message Format downlink option: short or long. - The short format is used when there is limited telemetry bandwidth - and is binary. The long format is in ASCII and is used for - logging to a Local Event Log and to an Event Message Port. -
    \anchor cfeadg_eventid Event ID - A numeric literal used to uniquely name an Application event. -
    \anchor cfeadg_eventtype Event Type - A numeric literal used to identify the type of an Application event. - An event type may be #CFE_EVS_DEBUG, #CFE_EVS_INFORMATION, - #CFE_EVS_ERROR, or #CFE_EVS_CRITICAL. -
    \anchor cfeadg_eventmessage Event Message - A data item used to notify the user and/or an external - \ref cfeadg_application "Application" of a significant event. - Event Messages include a time-stamp of when the message was - generated, a processor unique identifier, an - \ref cfeadg_applicationid "Application ID", the - \ref cfeadg_eventtype "Event Type" (DEBUG,INFO,ERROR or CRITICAL), - and \ref cfeadg_eventdata "Event Data". An Event Message can - either be real-time or playback from a Local Event Log. -
    -**/ - -/** - \page cfeapi cFE Application Programmer's Interface (API) Reference -

    Executive Services API

    -
      -
    • \ref CFEAPIESEntryExit -
        -
      • #CFE_ES_Main - \copybrief CFE_ES_Main -
      • #CFE_ES_ResetCFE - \copybrief CFE_ES_ResetCFE -
      -
    • \ref CFEAPIESAppControl -
        -
      • #CFE_ES_RestartApp - \copybrief CFE_ES_RestartApp -
      • #CFE_ES_ReloadApp - \copybrief CFE_ES_ReloadApp -
      • #CFE_ES_DeleteApp - \copybrief CFE_ES_DeleteApp -
      -
    • \ref CFEAPIESAppBehavior -
        -
      • #CFE_ES_RegisterApp - \copybrief CFE_ES_RegisterApp -
      • #CFE_ES_RunLoop - \copybrief CFE_ES_RunLoop -
      • #CFE_ES_WaitForStartupSync - \copybrief CFE_ES_WaitForStartupSync -
      • #CFE_ES_WaitForSystemState - \copybrief CFE_ES_WaitForSystemState -
      • #CFE_ES_IncrementTaskCounter - \copybrief CFE_ES_IncrementTaskCounter -
      • #CFE_ES_ExitApp - \copybrief CFE_ES_ExitApp -
      -
    • \ref CFEAPIESInfo -
        -
      • #CFE_ES_GetResetType - \copybrief CFE_ES_GetResetType -
      • #CFE_ES_GetAppID - \copybrief CFE_ES_GetAppID -
      • #CFE_ES_GetAppIDByName - \copybrief CFE_ES_GetAppIDByName -
      • #CFE_ES_GetAppName - \copybrief CFE_ES_GetAppName -
      • #CFE_ES_GetAppInfo - \copybrief CFE_ES_GetAppInfo -
      • #CFE_ES_GetTaskInfo - \copybrief CFE_ES_GetTaskInfo -
      -
    • \ref CFEAPIESChildTask -
        -
      • #CFE_ES_RegisterChildTask - \copybrief CFE_ES_RegisterChildTask -
      • #CFE_ES_CreateChildTask - \copybrief CFE_ES_CreateChildTask -
      • #CFE_ES_DeleteChildTask - \copybrief CFE_ES_DeleteChildTask -
      • #CFE_ES_ExitChildTask - \copybrief CFE_ES_ExitChildTask -
      -
    • \ref CFEAPIESCritData -
        -
      • #CFE_ES_RegisterCDS - \copybrief CFE_ES_RegisterCDS -
      • #CFE_ES_CopyToCDS - \copybrief CFE_ES_CopyToCDS -
      • #CFE_ES_RestoreFromCDS - \copybrief CFE_ES_RestoreFromCDS -
      -
    • \ref CFEAPIESMemManage -
        -
      • #CFE_ES_PoolCreate - \copybrief CFE_ES_PoolCreate -
      • #CFE_ES_PoolCreateEx - \copybrief CFE_ES_PoolCreateEx -
      • #CFE_ES_PoolCreateNoSem - \copybrief CFE_ES_PoolCreateNoSem -
      • #CFE_ES_GetPoolBuf - \copybrief CFE_ES_GetPoolBuf -
      • #CFE_ES_PutPoolBuf - \copybrief CFE_ES_PutPoolBuf -
      • #CFE_ES_GetMemPoolStats - \copybrief CFE_ES_GetMemPoolStats -
      • #CFE_ES_GetPoolBufInfo - \copybrief CFE_ES_GetPoolBufInfo -
      -
    • \ref CFEAPIESPerfMon -
        -
      • #CFE_ES_PerfLogEntry - \copybrief CFE_ES_PerfLogEntry -
      • #CFE_ES_PerfLogExit - \copybrief CFE_ES_PerfLogExit -
      • #CFE_ES_PerfLogAdd - \copybrief CFE_ES_PerfLogAdd -
      -
    • \ref CFEAPIESGenCount -
        -
      • #CFE_ES_RegisterGenCounter - \copybrief CFE_ES_RegisterGenCounter -
      • #CFE_ES_DeleteGenCounter - \copybrief CFE_ES_DeleteGenCounter -
      • #CFE_ES_IncrementGenCounter - \copybrief CFE_ES_IncrementGenCounter -
      • #CFE_ES_SetGenCount - \copybrief CFE_ES_SetGenCount -
      • #CFE_ES_GetGenCount - \copybrief CFE_ES_GetGenCount -
      • #CFE_ES_GetGenCounterIDByName - \copybrief CFE_ES_GetGenCounterIDByName -
      -
    • \ref CFEAPIESMisc -
        -
      • #CFE_ES_CalculateCRC - \copybrief CFE_ES_CalculateCRC -
      • #CFE_ES_WriteToSysLog - \copybrief CFE_ES_WriteToSysLog -
      • #CFE_ES_ProcessAsyncEvent - \copybrief CFE_ES_ProcessAsyncEvent -
      -
    - -

    Events Services API

    -
      -
    • \ref CFEAPIEVSReg -
        -
      • #CFE_EVS_Register - \copybrief CFE_EVS_Register -
      • #CFE_EVS_Unregister - \copybrief CFE_EVS_Unregister -
      -
    • \ref CFEAPIEVSSend -
        -
      • #CFE_EVS_SendEvent - \copybrief CFE_EVS_SendEvent -
      • #CFE_EVS_SendEventWithAppID - \copybrief CFE_EVS_SendEventWithAppID -
      • #CFE_EVS_SendTimedEvent - \copybrief CFE_EVS_SendTimedEvent -
      -
    • \ref CFEAPIEVSResetFilter -
        -
      • #CFE_EVS_ResetFilter - \copybrief CFE_EVS_ResetFilter -
      • #CFE_EVS_ResetAllFilters - \copybrief CFE_EVS_ResetAllFilters -
      -
    - -

    File Services API

    -
      -
    • \ref CFEAPIFSHeader -
        -
      • #CFE_FS_ReadHeader - \copybrief CFE_FS_ReadHeader -
      • #CFE_FS_InitHeader - \copybrief CFE_FS_InitHeader -
      • #CFE_FS_WriteHeader - \copybrief CFE_FS_WriteHeader -
      • #CFE_FS_SetTimestamp - \copybrief CFE_FS_SetTimestamp -
      -
    • \ref CFEAPIFSCompress -
        -
      • #CFE_FS_IsGzFile - \copybrief CFE_FS_IsGzFile -
      • #CFE_FS_Decompress - \copybrief CFE_FS_Decompress -
      • #CFE_FS_GetUncompressedFile - \copybrief CFE_FS_GetUncompressedFile -
      -
    • \ref CFEAPIFSUtil -
        -
      • #CFE_FS_ExtractFilenameFromPath - \copybrief CFE_FS_ExtractFilenameFromPath -
      -
    - -

    Software Bus API

    -
      -
    • \ref CFEAPISBPipe -
        -
      • #CFE_SB_CreatePipe - \copybrief CFE_SB_CreatePipe -
      • #CFE_SB_DeletePipe - \copybrief CFE_SB_DeletePipe -
      • #CFE_SB_SetPipeOpts - \copybrief CFE_SB_SetPipeOpts -
      • #CFE_SB_GetPipeOpts - \copybrief CFE_SB_GetPipeOpts -
      • #CFE_SB_GetPipeName - \copybrief CFE_SB_GetPipeName -
      • #CFE_SB_GetPipeIdByName - \copybrief CFE_SB_GetPipeIdByName -
      -
    • \ref CFEAPISBSubscription -
        -
      • #CFE_SB_Subscribe - \copybrief CFE_SB_Subscribe -
      • #CFE_SB_SubscribeEx - \copybrief CFE_SB_SubscribeEx -
      • #CFE_SB_SubscribeLocal - \copybrief CFE_SB_SubscribeLocal -
      • #CFE_SB_Unsubscribe - \copybrief CFE_SB_Unsubscribe -
      • #CFE_SB_UnsubscribeLocal - \copybrief CFE_SB_UnsubscribeLocal -
      -
    • \ref CFEAPISBMessage -
        -
      • #CFE_SB_SendMsg - \copybrief CFE_SB_SendMsg -
      • #CFE_SB_PassMsg - \copybrief CFE_SB_PassMsg -
      • #CFE_SB_RcvMsg - \copybrief CFE_SB_RcvMsg -
      -
    • \ref CFEAPISBZeroCopy -
        -
      • #CFE_SB_ZeroCopyGetPtr - \copybrief CFE_SB_ZeroCopyGetPtr -
      • #CFE_SB_ZeroCopyReleasePtr - \copybrief CFE_SB_ZeroCopyReleasePtr -
      • #CFE_SB_ZeroCopySend - \copybrief CFE_SB_ZeroCopySend -
      • #CFE_SB_ZeroCopyPass - \copybrief CFE_SB_ZeroCopyPass -
      -
    • \ref CFEAPISBSetMessage -
        -
      • #CFE_SB_InitMsg - \copybrief CFE_SB_InitMsg -
      • #CFE_SB_SetMsgId - \copybrief CFE_SB_SetMsgId -
      • #CFE_SB_SetUserDataLength - \copybrief CFE_SB_SetUserDataLength -
      • #CFE_SB_SetTotalMsgLength - \copybrief CFE_SB_SetTotalMsgLength -
      • #CFE_SB_SetMsgTime - \copybrief CFE_SB_SetMsgTime -
      • #CFE_SB_TimeStampMsg - \copybrief CFE_SB_TimeStampMsg -
      • #CFE_SB_SetCmdCode - \copybrief CFE_SB_SetCmdCode -
      • #CFE_SB_MessageStringSet - \copybrief CFE_SB_MessageStringSet -
      -
    • \ref CFEAPIGetMessage -
        -
      • #CFE_SB_GetUserData - \copybrief CFE_SB_GetUserData -
      • #CFE_SB_GetMsgId - \copybrief CFE_SB_GetMsgId -
      • #CFE_SB_GetUserDataLength - \copybrief CFE_SB_GetUserDataLength -
      • #CFE_SB_GetTotalMsgLength - \copybrief CFE_SB_GetTotalMsgLength -
      • #CFE_SB_GetMsgTime - \copybrief CFE_SB_GetMsgTime -
      • #CFE_SB_GetCmdCode - \copybrief CFE_SB_GetCmdCode -
      • #CFE_SB_GetLastSenderId - \copybrief CFE_SB_GetLastSenderId -
      • #CFE_SB_MessageStringGet - \copybrief CFE_SB_MessageStringGet -
      -
    • \ref CFEAPISBChecksum -
        -
      • #CFE_SB_GenerateChecksum - \copybrief CFE_SB_GenerateChecksum -
      • #CFE_SB_GetChecksum - \copybrief CFE_SB_GetChecksum -
      • #CFE_SB_ValidateChecksum - \copybrief CFE_SB_ValidateChecksum -
      -
    • \ref CFEAPISBMessageID -
        -
      • #CFE_SB_MsgId_Equal - \copybrief CFE_SB_MsgId_Equal -
      • #CFE_SB_MsgIdToValue - \copybrief CFE_SB_MsgIdToValue -
      • #CFE_SB_ValueToMsgId - \copybrief CFE_SB_ValueToMsgId -
      -
    - -

    Table Services API

    -
      -
    • \ref CFEAPITBLRegistration -
        -
      • #CFE_TBL_Register - \copybrief CFE_TBL_Register -
      • #CFE_TBL_Share - \copybrief CFE_TBL_Share -
      • #CFE_TBL_Unregister - \copybrief CFE_TBL_Unregister -
      -
    • \ref CFEAPITBLManage -
        -
      • #CFE_TBL_Load - \copybrief CFE_TBL_Load -
      • #CFE_TBL_Update - \copybrief CFE_TBL_Update -
      • #CFE_TBL_Validate - \copybrief CFE_TBL_Validate -
      • #CFE_TBL_Manage - \copybrief CFE_TBL_Manage -
      • #CFE_TBL_DumpToBuffer - \copybrief CFE_TBL_DumpToBuffer -
      • #CFE_TBL_Modified - \copybrief CFE_TBL_Modified -
      -
    • \ref CFEAPITBLAccess -
        -
      • #CFE_TBL_GetAddress - \copybrief CFE_TBL_GetAddress -
      • #CFE_TBL_GetAddresses - \copybrief CFE_TBL_GetAddresses -
      • #CFE_TBL_ReleaseAddress - \copybrief CFE_TBL_ReleaseAddress -
      • #CFE_TBL_ReleaseAddresses - \copybrief CFE_TBL_ReleaseAddresses -
      -
    • \ref CFEAPITBLInfo -
        -
      • #CFE_TBL_GetStatus - \copybrief CFE_TBL_GetStatus -
      • #CFE_TBL_GetInfo - \copybrief CFE_TBL_GetInfo -
      • #CFE_TBL_NotifyByMessage - \copybrief CFE_TBL_NotifyByMessage -
      -
    - -

    Time Services API

    -
      -
    • \ref CFEAPITIMEGetCurrent -
        -
      • #CFE_TIME_GetTime - \copybrief CFE_TIME_GetTime -
      • #CFE_TIME_GetTAI - \copybrief CFE_TIME_GetTAI -
      • #CFE_TIME_GetUTC - \copybrief CFE_TIME_GetUTC -
      • #CFE_TIME_GetMET - \copybrief CFE_TIME_GetMET -
      • #CFE_TIME_GetMETseconds - \copybrief CFE_TIME_GetMETseconds -
      • #CFE_TIME_GetMETsubsecs - \copybrief CFE_TIME_GetMETsubsecs -
      -
    • \ref CFEAPITIMEGetInfo -
        -
      • #CFE_TIME_GetSTCF - \copybrief CFE_TIME_GetSTCF -
      • #CFE_TIME_GetLeapSeconds - \copybrief CFE_TIME_GetLeapSeconds -
      • #CFE_TIME_GetClockState - \copybrief CFE_TIME_GetClockState -
      • #CFE_TIME_GetClockInfo - \copybrief CFE_TIME_GetClockInfo -
      -
    • \ref CFEAPITIMEArithmetic -
        -
      • #CFE_TIME_Add - \copybrief CFE_TIME_Add -
      • #CFE_TIME_Subtract - \copybrief CFE_TIME_Subtract -
      • #CFE_TIME_Compare - \copybrief CFE_TIME_Compare -
      -
    • \ref CFEAPITIMEConvert -
        -
      • #CFE_TIME_MET2SCTime - \copybrief CFE_TIME_MET2SCTime -
      • #CFE_TIME_Sub2MicroSecs - \copybrief CFE_TIME_Sub2MicroSecs -
      • #CFE_TIME_Micro2SubSecs - \copybrief CFE_TIME_Micro2SubSecs -
      • #CFE_TIME_CFE2FSSeconds - \copybrief CFE_TIME_CFE2FSSeconds -
      • #CFE_TIME_FS2CFESeconds - \copybrief CFE_TIME_FS2CFESeconds -
      -
    • \ref CFEAPITIMEExternSource -
        -
      • #CFE_TIME_ExternalTone - \copybrief CFE_TIME_ExternalTone -
      • #CFE_TIME_ExternalMET - \copybrief CFE_TIME_ExternalMET -
      • #CFE_TIME_ExternalGPS - \copybrief CFE_TIME_ExternalGPS -
      • #CFE_TIME_ExternalTime - \copybrief CFE_TIME_ExternalTime -
      • #CFE_TIME_RegisterSynchCallback - \copybrief CFE_TIME_RegisterSynchCallback -
      • #CFE_TIME_UnregisterSynchCallback - \copybrief CFE_TIME_UnregisterSynchCallback -
      -
    • \ref CFEAPITIMEMisc -
        -
      • #CFE_TIME_Print - \copybrief CFE_TIME_Print -
      • #CFE_TIME_Local1HzISR - \copybrief CFE_TIME_Local1HzISR -
      -
    -**/ - diff --git a/fsw/cfe-core/src/es/cfe_es_cds.h b/fsw/cfe-core/src/es/cfe_es_cds.h index 8d910e01e..ee32f7544 100644 --- a/fsw/cfe-core/src/es/cfe_es_cds.h +++ b/fsw/cfe-core/src/es/cfe_es_cds.h @@ -58,6 +58,8 @@ #define CFE_ES_CDS_MUT_REG_VALUE 0 /**< \brief Initial Value of CDS Registry Access Mutex */ #define CFE_ES_CDS_NOT_FOUND (uint32)(0xffffffff) +/** \} */ + /* ** Type Definitions */ @@ -121,9 +123,8 @@ int32 CFE_ES_UpdateCDSRegistry(void); ** \par Assumptions, External Events, and Notes: ** None ** -** \param[in] AppIdPtr Pointer to value that will hold AppID on return. +** \param[in, out] AppIdPtr Pointer to value that will hold AppID on return. *AppIdPtr is the AppID as obtained from #CFE_ES_GetAppID. ** -** \param[out] *AppIdPtr The AppID as obtained from #CFE_ES_GetAppID ** ** \retval #CFE_SUCCESS \copydoc CFE_SUCCESS ** \retval #CFE_ES_ERR_APPID \copydoc CFE_ES_ERR_APPID @@ -144,17 +145,15 @@ int32 CFE_ES_CDS_ValidateAppID(uint32 *AppIdPtr); ** \par Assumptions, External Events, and Notes: ** Note: AppName portion will be truncated to OS_MAX_API_NAME. ** -** \param[in] FullCDSName pointer to character buffer of #CFE_ES_CDS_MAX_FULL_NAME_LEN size -** that will be filled with the processor specific CDS Name. +** \param[in, out] FullCDSName pointer to character buffer of #CFE_ES_CDS_MAX_FULL_NAME_LEN size +** that will be filled with the processor specific CDS Name. *FullCDSName is the processor specific CDS Name of the form "AppName.CDSName". ** ** \param[in] CDSName pointer to character string containing the Application's local name for ** the CDS. ** ** \param[in] ThisAppId the Application ID of the Application making the call. ** -** \param[out] *FullCDSName processor specific CDS Name of the form "AppName.CDSName". ** -** \retval None ******************************************************************************/ void CFE_ES_FormCDSName(char *FullCDSName, const char *CDSName, uint32 ThisAppId); @@ -173,7 +172,7 @@ void CFE_ES_FormCDSName(char *FullCDSName, const char *CDSName, uint32 ThisAppId ** CDS Name (of the format "AppName.CDSName"). ** ** \retval #CFE_ES_CDS_NOT_FOUND or the Index into Registry for Table with specified name -** +** ******************************************************************************/ int32 CFE_ES_FindCDSInRegistry(const char *CDSName); diff --git a/fsw/cfe-core/src/inc/cfe_es.h b/fsw/cfe-core/src/inc/cfe_es.h index b52d0cbe9..6df04cfad 100644 --- a/fsw/cfe-core/src/inc/cfe_es.h +++ b/fsw/cfe-core/src/inc/cfe_es.h @@ -490,9 +490,11 @@ int32 CFE_ES_DeleteApp(uint32 AppID); ** \par Assumptions, External Events, and Notes: ** None ** -** \param[in] ExitStatus . -** -** \return Execution status, see \ref CFEReturnCodes +** \param[in] ExitStatus Acceptable values are: \arg #CFE_ES_RunStatus_APP_EXIT - \copybrief CFE_ES_RunStatus_APP_EXIT + \arg #CFE_ES_RunStatus_APP_ERROR - \copybrief CFE_ES_RunStatus_APP_ERROR + \arg #CFE_ES_RunStatus_CORE_APP_INIT_ERROR - \copybrief CFE_ES_RunStatus_CORE_APP_INIT_ERROR + \arg #CFE_ES_RunStatus_CORE_APP_RUNTIME_ERROR - \copybrief CFE_ES_RunStatus_CORE_APP_RUNTIME_ERROR +** ** ** \sa #CFE_ES_RunLoop, #CFE_ES_RegisterApp ** @@ -645,12 +647,11 @@ void CFE_ES_IncrementTaskCounter(void); ** \par Assumptions, External Events, and Notes: ** None ** -** \param[in] ResetSubtypePtr Pointer to \c uint32 type variable in which the Reset Sub-Type will be stored. -** The caller can set this pointer to NULL if the Sub-Type is of no interest. -** -** \param[out] *ResetSubtypePtr If the provided pointer was not \c NULL, the Reset Sub-Type is stored at the given address. +** \param[in, out] ResetSubtypePtr Pointer to \c uint32 type variable in which the Reset Sub-Type will be stored. +** The caller can set this pointer to NULL if the Sub-Type is of no interest. \n *ResetSubtypePtr If the provided pointer was not \c NULL, the Reset Sub-Type is stored at the given address. ** For a list of possible Sub-Type values, see \link #CFE_PSP_RST_SUBTYPE_POWER_CYCLE "Reset Sub-Types" \endlink. ** +** ** \return Processor reset type ** \retval #CFE_PSP_RST_TYPE_POWERON \copybrief CFE_PSP_RST_TYPE_POWERON ** \retval #CFE_PSP_RST_TYPE_PROCESSOR \copybrief CFE_PSP_RST_TYPE_PROCESSOR @@ -670,9 +671,8 @@ int32 CFE_ES_GetResetType(uint32 *ResetSubtypePtr); ** \par Assumptions, External Events, and Notes: ** NOTE: \b All tasks associated with the Application would return the same Application ID. ** -** \param[in] AppIdPtr Pointer to variable that is to receive the Application's ID. +** \param[in] AppIdPtr Pointer to variable that is to receive the Application's ID. *AppIdPtr is the application ID of the calling Application. ** -** \param[out] *AppIdPtr Application ID of the calling Application. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -695,11 +695,10 @@ int32 CFE_ES_GetAppID(uint32 *AppIdPtr); ** \par Assumptions, External Events, and Notes: ** None ** -** \param[in] AppIdPtr Pointer to variable that is to receive the Application's ID. +** \param[in] AppIdPtr Pointer to variable that is to receive the Application's ID. *AppIdPtr is the application ID of the calling Application. ** ** \param[in] AppName Pointer to null terminated character string containing an Application name. ** -** \param[out] *AppIdPtr Application ID of the calling Application. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -723,8 +722,9 @@ int32 CFE_ES_GetAppIDByName(uint32 *AppIdPtr, const char *AppName); ** In the case of a failure (#CFE_ES_ERR_APPID), an empty string is returned. #CFE_ES_ERR_APPID ** will be returned if the specified Application ID (AppId) is invalid or not in use. ** -** \param[in] AppName Pointer to a character array of at least \c BufferLength in size that will -** be filled with the appropriate Application name. +** \param[in, out] AppName Pointer to a character array of at least \c BufferLength in size that will +** be filled with the appropriate Application name. *AppName is the null terminated Application name of the Application associated with the +** specified Application ID ** ** \param[in] AppId Application ID of Application whose name is being requested. ** @@ -732,8 +732,6 @@ int32 CFE_ES_GetAppIDByName(uint32 *AppIdPtr, const char *AppName); ** into the \c AppName buffer. This routine will truncate the name to this length, ** if necessary. ** -** \param[out] *AppName Null terminated Application name of the Application associated with the -** specified Application ID. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -756,13 +754,12 @@ int32 CFE_ES_GetAppName(char *AppName, uint32 AppId, uint32 BufferLength); ** \par Assumptions, External Events, and Notes: ** None ** -** \param[in] AppInfo Pointer to a \c CFE_ES_AppInfo_t structure that holds the specific -** Application information. +** \param[in, out] AppInfo Pointer to a \c CFE_ES_AppInfo_t structure that holds the specific +** Application information. *AppInfo is the filled out \c CFE_ES_AppInfo_t structure containing the +** App Name, and application memory addresses among other fields. ** ** \param[in] AppId Application ID of Application whose name is being requested. ** -** \param[out] *AppInfo Filled out \c CFE_ES_AppInfo_t structure containing the -** App Name, and application memory addresses among other fields. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -786,13 +783,12 @@ int32 CFE_ES_GetAppInfo(CFE_ES_AppInfo_t *AppInfo, uint32 AppId); ** \par Assumptions, External Events, and Notes: ** None ** -** \param[in] TaskInfo Pointer to a \c CFE_ES_TaskInfo_t structure that holds the specific -** task information. +** \param[in, out] TaskInfo Pointer to a \c CFE_ES_TaskInfo_t structure that holds the specific +** task information. *TaskInfo is the filled out \c CFE_ES_TaskInfo_t structure containing the +** Task Name, Parent App Name, Parent App ID among other fields. ** ** \param[in] TaskId Application ID of Application whose name is being requested. ** -** \param[out] *TaskInfo Filled out \c CFE_ES_TaskInfo_t structure containing the -** Task Name, Parent App Name, Parent App ID among other fields. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -839,7 +835,7 @@ int32 CFE_ES_RegisterChildTask(void); ** \par Assumptions, External Events, and Notes: ** None ** -** \param[in] TaskIdPtr A pointer to a variable that will be filled in with the new task's ID. +** \param[in, out] TaskIdPtr A pointer to a variable that will be filled in with the new task's ID. *TaskIdPtr is the Task ID of the newly created child task. ** ** \param[in] TaskName A pointer to a string containing the desired name of the new task. ** This can be up to #OS_MAX_API_NAME characters, including the trailing null. @@ -859,8 +855,6 @@ int32 CFE_ES_RegisterChildTask(void); ** ** \param[in] Flags Reserved for future expansion. ** -** \param[out] *TaskIdPtr The Task ID of the newly created child task. -** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS ** \retval #CFE_ES_ERR_CHILD_TASK_CREATE \copybrief CFE_ES_ERR_CHILD_TASK_CREATE @@ -909,7 +903,7 @@ int32 CFE_ES_DeleteChildTask(uint32 TaskId); ** \par Assumptions, External Events, and Notes: ** This function cannot be called from an Application's Main Task. ** -** \return This function does not return a value, but if it does return +** \note This function does not return a value, but if it does return ** at all, it is assumed that the Task was either unregistered or ** this function was called from a cFE Application's main task. ** @@ -1011,15 +1005,14 @@ void CFE_ES_ProcessAsyncEvent(void); ** \par Assumptions, External Events, and Notes: ** None ** -** \param[in] HandlePtr Pointer Application's variable that will contain the CDS Memory Block Handle. +** \param[in, out] HandlePtr Pointer Application's variable that will contain the CDS Memory Block Handle. *HandlePtr is the handle of the CDS block that can be used in +** #CFE_ES_CopyToCDS and #CFE_ES_RestoreFromCDS. ** ** \param[in] BlockSize The number of bytes needed in the CDS. ** ** \param[in] Name A pointer to a character string containing an application ** unique name of #CFE_MISSION_ES_CDS_MAX_NAME_LENGTH characters or less. ** -** \param[out] *HandlePtr The handle of the CDS block that can be used in -** #CFE_ES_CopyToCDS and #CFE_ES_RestoreFromCDS. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS The memory block was successfully created in the CDS. @@ -1077,9 +1070,7 @@ int32 CFE_ES_CopyToCDS(CFE_ES_CDSHandle_t Handle, void *DataToCopy); ** ** \param[in] Handle The handle of the CDS block that was previously obtained from #CFE_ES_RegisterCDS. ** -** \param[in] RestoreToMemory A Pointer to the block of memory that is to be restored with the contents of the CDS. -** -** \param[out] *RestoreToMemory The contents of the specified CDS. +** \param[in, out] RestoreToMemory A Pointer to the block of memory that is to be restored with the contents of the CDS. *RestoreToMemory is the contents of the specified CDS. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -1109,15 +1100,13 @@ int32 CFE_ES_RestoreFromCDS(void *RestoreToMemory, CFE_ES_CDSHandle_t Handle); ** -# The start address of the pool must be 32-bit aligned ** -# 168 bytes are used for internal bookkeeping, therefore, they will not be available for allocation. ** -** \param[in] HandlePtr A pointer to the variable the caller wishes to have the memory pool handle kept in. +** \param[in, out] HandlePtr A pointer to the variable the caller wishes to have the memory pool handle kept in. *HandlePtr is the memory pool handle. ** ** \param[in] MemPtr A Pointer to the pool of memory created by the calling application. This address must ** be on a 32-bit boundary. ** ** \param[in] Size The size of the pool of memory. Note that this must be an integral number of 32 bit words. ** -** \param[out] *HandlePtr The memory pool handle. -** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS ** \retval #CFE_ES_BAD_ARGUMENT \copybrief CFE_ES_BAD_ARGUMENT @@ -1140,15 +1129,13 @@ int32 CFE_ES_PoolCreateNoSem(CFE_ES_MemHandle_t *HandlePtr, uint8 *MemPtr, uint3 ** -# The start address of the pool must be 32-bit aligned ** -# 168 bytes are used for internal bookkeeping, therefore, they will not be available for allocation. ** -** \param[in] HandlePtr A pointer to the variable the caller wishes to have the memory pool handle kept in. +** \param[in, out] HandlePtr A pointer to the variable the caller wishes to have the memory pool handle kept in. *HandlePtr is the memory pool handle. ** ** \param[in] MemPtr A Pointer to the pool of memory created by the calling application. This address must ** be on a 32-bit boundary. ** ** \param[in] Size The size of the pool of memory. Note that this must be an integral number of 32 bit words. ** -** \param[out] *HandlePtr The memory pool handle. -** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS ** \retval #CFE_ES_BAD_ARGUMENT \copybrief CFE_ES_BAD_ARGUMENT @@ -1170,7 +1157,7 @@ int32 CFE_ES_PoolCreate(CFE_ES_MemHandle_t *HandlePtr, uint8 *MemPtr, uint32 Siz ** -# The start address of the pool must be 32-bit aligned ** -# 168 bytes are used for internal bookkeeping, therefore, they will not be available for allocation. ** -** \param[in] HandlePtr A pointer to the variable the caller wishes to have the memory pool handle kept in. +** \param[in, out] HandlePtr A pointer to the variable the caller wishes to have the memory pool handle kept in. *HandlePtr is the memory pool handle. ** ** \param[in] MemPtr A Pointer to the pool of memory created by the calling application. This address must ** be on a 32-bit boundary. @@ -1187,8 +1174,6 @@ int32 CFE_ES_PoolCreate(CFE_ES_MemHandle_t *HandlePtr, uint8 *MemPtr, uint32 Siz ** \param[in] UseMutex Flag indicating whether the new memory pool will be processing with mutex handling or not. ** Valid parameter values are #CFE_ES_USE_MUTEX and #CFE_ES_NO_MUTEX ** -** \param[out] *HandlePtr The memory pool handle. -** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS ** \retval #CFE_ES_BAD_ARGUMENT \copybrief CFE_ES_BAD_ARGUMENT @@ -1208,14 +1193,12 @@ int32 CFE_ES_PoolCreateEx(CFE_ES_MemHandle_t *HandlePtr, uint8 *MemPtr, uint32 S ** \par Assumptions, External Events, and Notes: ** -# The size allocated from the memory pool is, at a minimum, 12 bytes more than requested. ** -** \param[in] BufPtr A pointer to the Application's pointer in which will be stored the address of the allocated memory buffer. +** \param[in, out] BufPtr A pointer to the Application's pointer in which will be stored the address of the allocated memory buffer. *BufPtr is the address of the requested buffer. ** ** \param[in] HandlePtr The handle to the memory pool as returned by #CFE_ES_PoolCreate or #CFE_ES_PoolCreateNoSem. ** ** \param[in] Size The size of the buffer requested. NOTE: The size allocated may be larger. ** -** \param[out] *BufPtr The address of the requested buffer. -** ** \return Bytes Allocated, or error code \ref CFEReturnCodes ** \retval #CFE_ES_ERR_MEM_HANDLE \copybrief CFE_ES_ERR_MEM_HANDLE ** \retval #CFE_ES_ERR_MEM_BLOCK_SIZE \copybrief CFE_ES_ERR_MEM_BLOCK_SIZE @@ -1283,12 +1266,11 @@ int32 CFE_ES_PutPoolBuf(CFE_ES_MemHandle_t HandlePtr, uint32 *BufPtr); ** \par Assumptions, External Events, and Notes: ** None ** -** \param[in] BufPtr Pointer to #CFE_ES_MemPoolStats_t data structure to be -** filled with memory statistics. +** \param[in, out] BufPtr Pointer to #CFE_ES_MemPoolStats_t data structure to be +** filled with memory statistics. *BufPtr is the Memory Pool Statistics stored in given data structure. ** ** \param[in] Handle The handle to the memory pool whose statistics are desired. ** -** \param[out] *BufPtr Memory Pool Statistics stored in given data structure. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS diff --git a/fsw/cfe-core/src/inc/cfe_fs.h b/fsw/cfe-core/src/inc/cfe_fs.h index e7fcf2d6a..402dee6d0 100644 --- a/fsw/cfe-core/src/inc/cfe_fs.h +++ b/fsw/cfe-core/src/inc/cfe_fs.h @@ -91,10 +91,8 @@ ** \param[in] FileDes File Descriptor obtained from a previous call to #OS_open ** that is associated with the file whose header is to be read. ** -** \param[in] Hdr Pointer to a variable of type #CFE_FS_Header_t that will be -** filled with the contents of the Standard cFE File Header. -** -** \param[out] *Hdr Contents of the Standard cFE File Header for the specified file. +** \param[in, out] Hdr Pointer to a variable of type #CFE_FS_Header_t that will be +** filled with the contents of the Standard cFE File Header. *Hdr is the contents of the Standard cFE File Header for the specified file. ** ** \return Execution status, see \ref CFEReturnCodes ** @@ -151,10 +149,8 @@ void CFE_FS_InitHeader(CFE_FS_Header_t *Hdr, const char *Description, uint32 Sub ** \param[in] FileDes File Descriptor obtained from a previous call to #OS_open ** that is associated with the file whose header is to be read. ** -** \param[in] Hdr Pointer to a variable of type #CFE_FS_Header_t that will be -** filled with the contents of the Standard cFE File Header. -** -** \param[out] *Hdr Contents of the Standard cFE File Header for the specified file. +** \param[in, out] Hdr Pointer to a variable of type #CFE_FS_Header_t that will be +** filled with the contents of the Standard cFE File Header. *Hdr is the contents of the Standard cFE File Header for the specified file. ** ** \return Execution status, see \ref CFEReturnCodes ** diff --git a/fsw/cfe-core/src/inc/cfe_sb.h b/fsw/cfe-core/src/inc/cfe_sb.h index 0b515e83b..7f92c3794 100644 --- a/fsw/cfe-core/src/inc/cfe_sb.h +++ b/fsw/cfe-core/src/inc/cfe_sb.h @@ -153,7 +153,7 @@ typedef union { uint32 Dword; /**< \brief Forces minimum of 32-bit alignment for this object */ uint8 Byte[sizeof(CCSDS_PriHdr_t)]; /**< \brief Allows byte-level access */ }CFE_SB_Msg_t; - + /** \brief Generic Software Bus Command Header Type Definition */ typedef union { CCSDS_CommandPacket_t Cmd; @@ -170,15 +170,15 @@ typedef union { #define CFE_SB_TLM_HDR_SIZE (sizeof(CFE_SB_TlmHdr_t))/**< \brief Size of #CFE_SB_TlmHdr_t in bytes */ /** \brief CFE_SB_TimeOut_t to primitive type definition -** +** ** Internally used by SB in the #CFE_SB_RcvMsg API. Translated from the -** input parmater named TimeOut which specifies the maximum time in +** input parmater named TimeOut which specifies the maximum time in ** milliseconds that the caller wants to wait for a message. */ typedef uint32 CFE_SB_TimeOut_t; -/** \brief CFE_SB_PipeId_t to primitive type definition -** +/** \brief CFE_SB_PipeId_t to primitive type definition +** ** Software Bus pipe identifier used in many SB APIs */ typedef uint8 CFE_SB_PipeId_t; @@ -189,8 +189,8 @@ typedef CFE_SB_Msg_t *CFE_SB_MsgPtr_t; /** \brief CFE_SB_MsgPayloadPtr_t defined as an opaque pointer to a message Payload portion */ typedef uint8 *CFE_SB_MsgPayloadPtr_t; -/** \brief CFE_SB_ZeroCopyHandle_t to primitive type definition -** +/** \brief CFE_SB_ZeroCopyHandle_t to primitive type definition +** ** Software Zero Copy handle used in many SB APIs */ typedef cpuaddr CFE_SB_ZeroCopyHandle_t; @@ -199,7 +199,7 @@ typedef cpuaddr CFE_SB_ZeroCopyHandle_t; ** ** Currently an unused parameter in #CFE_SB_SubscribeEx ** Intended to be used for interprocessor communication only -**/ +**/ typedef struct { uint8 Priority;/**< \brief Specify high(1) or low(0) message priority for off-board routing, currently unused */ uint8 Reliability;/**< \brief Specify high(1) or low(0) message transfer reliability for off-board routing, currently unused */ @@ -210,7 +210,7 @@ extern CFE_SB_Qos_t CFE_SB_Default_Qos;/**< \brief Defines a default priority a /** \brief Message Sender Identification Type Definition ** -** Parameter used in #CFE_SB_GetLastSenderId API which allows the receiver of a message +** Parameter used in #CFE_SB_GetLastSenderId API which allows the receiver of a message ** to validate the sender of the message. **/ typedef struct { @@ -225,32 +225,30 @@ typedef struct { */ /*****************************************************************************/ -/** +/** ** \brief Creates a new software bus pipe. ** ** \par Description -** This routine creates and initializes an input pipe that the calling -** application can use to receive software bus messages. By default, no -** messages are routed to the new pipe. So, the application must use -** #CFE_SB_Subscribe to specify which messages it wants to receive on +** This routine creates and initializes an input pipe that the calling +** application can use to receive software bus messages. By default, no +** messages are routed to the new pipe. So, the application must use +** #CFE_SB_Subscribe to specify which messages it wants to receive on ** this pipe. ** ** \par Assumptions, External Events, and Notes: ** None ** -** \param[in] PipeIdPtr A pointer to a variable of type #CFE_SB_PipeId_t, -** which will be filled in with the pipe ID information -** by the #CFE_SB_CreatePipe routine. +** \param[in, out] PipeIdPtr A pointer to a variable of type #CFE_SB_PipeId_t, +** which will be filled in with the pipe ID information +** by the #CFE_SB_CreatePipe routine. *PipeIdPtr is the identifier for the created pipe. ** -** \param[in] Depth The maximum number of messages that will be allowed on -** this pipe at one time. +** \param[in] Depth The maximum number of messages that will be allowed on +** this pipe at one time. ** -** \param[in] PipeName A string to be used to identify this pipe in error messages -** and routing information telemetry. The string must be no -** longer than #OS_MAX_API_NAME (including terminator). -** Longer strings will be truncated. -** -** \param[out] *PipeIdPtr The identifier for the created pipe. +** \param[in] PipeName A string to be used to identify this pipe in error messages +** and routing information telemetry. The string must be no +** longer than #OS_MAX_API_NAME (including terminator). +** Longer strings will be truncated. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -265,13 +263,13 @@ int32 CFE_SB_CreatePipe(CFE_SB_PipeId_t *PipeIdPtr, const char *PipeName); /*****************************************************************************/ -/** +/** ** \brief Delete a software bus pipe. ** ** \par Description -** This routine deletes an input pipe and cleans up all data structures -** associated with the pipe. All subscriptions made for this pipe by -** calls to #CFE_SB_Subscribe will be automatically removed from the +** This routine deletes an input pipe and cleans up all data structures +** associated with the pipe. All subscriptions made for this pipe by +** calls to #CFE_SB_Subscribe will be automatically removed from the ** SB routing tables. Any messages in the pipe will be discarded. ** ** Applications should not call this routine for all of their @@ -283,7 +281,7 @@ int32 CFE_SB_CreatePipe(CFE_SB_PipeId_t *PipeIdPtr, ** None ** ** \param[in] PipeId The pipe ID (obtained previously from #CFE_SB_CreatePipe) -** of the pipe to be deleted. +** of the pipe to be deleted. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -380,7 +378,7 @@ int32 CFE_SB_GetPipeIdByName(CFE_SB_PipeId_t *PipeIdPtr, const char *PipeName); */ /*****************************************************************************/ -/** +/** ** \brief Subscribe to a message on the software bus ** ** \par Description @@ -396,17 +394,17 @@ int32 CFE_SB_GetPipeIdByName(CFE_SB_PipeId_t *PipeIdPtr, const char *PipeName); ** shortest possible time, the developer may consider holding off its ** subscription until other applications have subscribed to the message. ** -** \param[in] MsgId The message ID of the message to be subscribed to. +** \param[in] MsgId The message ID of the message to be subscribed to. ** -** \param[in] PipeId The pipe ID of the pipe the subscribed message -** should be sent to. +** \param[in] PipeId The pipe ID of the pipe the subscribed message +** should be sent to. ** -** \param[in] Quality The requested Quality of Service (QoS) required of +** \param[in] Quality The requested Quality of Service (QoS) required of ** the messages. Most callers will use #CFE_SB_Default_Qos ** for this parameter. ** ** \param[in] MsgLim The maximum number of messages with this Message ID to -** allow in this pipe at the same time. +** allow in this pipe at the same time. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -423,13 +421,13 @@ int32 CFE_SB_SubscribeEx(CFE_SB_MsgId_t MsgId, uint16 MsgLim); /*****************************************************************************/ -/** +/** ** \brief Subscribe to a message on the software bus with default parameters ** ** \par Description -** This routine adds the specified pipe to the destination list for -** the specified message ID. This is the same as #CFE_SB_SubscribeEx -** with the Quality field set to #CFE_SB_Default_Qos and MsgLim set +** This routine adds the specified pipe to the destination list for +** the specified message ID. This is the same as #CFE_SB_SubscribeEx +** with the Quality field set to #CFE_SB_Default_Qos and MsgLim set ** to #CFE_PLATFORM_SB_DEFAULT_MSG_LIMIT (4). ** ** \par Assumptions, External Events, and Notes: @@ -441,10 +439,10 @@ int32 CFE_SB_SubscribeEx(CFE_SB_MsgId_t MsgId, ** shortest possible time, the developer may consider holding off its ** subscription until other applications have subscribed to the message. ** -** \param[in] MsgId The message ID of the message to be subscribed to. +** \param[in] MsgId The message ID of the message to be subscribed to. ** -** \param[in] PipeId The pipe ID of the pipe the subscribed message -** should be sent to. +** \param[in] PipeId The pipe ID of the pipe the subscribed message +** should be sent to. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -458,27 +456,27 @@ int32 CFE_SB_SubscribeEx(CFE_SB_MsgId_t MsgId, int32 CFE_SB_Subscribe(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId); /*****************************************************************************/ -/** +/** ** \brief Subscribe to a message while keeping the request local to a cpu ** ** \par Description -** This routine adds the specified pipe to the destination list for -** the specified message ID. This is similar to #CFE_SB_SubscribeEx -** with the Quality field set to #CFE_SB_Default_Qos and MsgLim set +** This routine adds the specified pipe to the destination list for +** the specified message ID. This is similar to #CFE_SB_SubscribeEx +** with the Quality field set to #CFE_SB_Default_Qos and MsgLim set ** to #CFE_PLATFORM_SB_DEFAULT_MSG_LIMIT, but will not report the subscription. ** Subscription Reporting is enabled for interprocessor communication -** by way of the Software Bus Network (SBN) Application. +** by way of the Software Bus Network (SBN) Application. ** ** \par Assumptions, External Events, and Notes: ** - This API is typically only used by Software Bus Network (SBN) Application ** -** \param[in] MsgId The message ID of the message to be subscribed to. +** \param[in] MsgId The message ID of the message to be subscribed to. ** -** \param[in] PipeId The pipe ID of the pipe the subscribed message -** should be sent to. +** \param[in] PipeId The pipe ID of the pipe the subscribed message +** should be sent to. ** ** \param[in] MsgLim The maximum number of messages with this Message ID to -** allow in this pipe at the same time. +** allow in this pipe at the same time. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -494,20 +492,20 @@ int32 CFE_SB_SubscribeLocal(CFE_SB_MsgId_t MsgId, uint16 MsgLim); /*****************************************************************************/ -/** +/** ** \brief Remove a subscription to a message on the software bus ** ** \par Description -** This routine removes the specified pipe from the destination +** This routine removes the specified pipe from the destination ** list for the specified message ID. ** ** \par Assumptions, External Events, and Notes: ** None ** -** \param[in] MsgId The message ID of the message to be unsubscribed. +** \param[in] MsgId The message ID of the message to be unsubscribed. ** -** \param[in] PipeId The pipe ID of the pipe the subscribed message -** should no longer be sent to. +** \param[in] PipeId The pipe ID of the pipe the subscribed message +** should no longer be sent to. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -519,20 +517,20 @@ int32 CFE_SB_SubscribeLocal(CFE_SB_MsgId_t MsgId, int32 CFE_SB_Unsubscribe(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId); /*****************************************************************************/ -/** +/** ** \brief Remove a subscription to a message on the software bus on the current CPU ** ** \par Description -** This routine removes the specified pipe from the destination +** This routine removes the specified pipe from the destination ** list for the specified message ID on the current CPU. ** ** \par Assumptions, External Events, and Notes: ** - This API is typically only used by Software Bus Network (SBN) Application ** -** \param[in] MsgId The message ID of the message to be unsubscribed. +** \param[in] MsgId The message ID of the message to be unsubscribed. ** -** \param[in] PipeId The pipe ID of the pipe the subscribed message -** should no longer be sent to. +** \param[in] PipeId The pipe ID of the pipe the subscribed message +** should no longer be sent to. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -549,26 +547,26 @@ int32 CFE_SB_UnsubscribeLocal(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId); */ /*****************************************************************************/ -/** +/** ** \brief Send a software bus message ** ** \par Description -** This routine sends the specified message to all subscribers. The -** software bus will read the message ID from the message header to +** This routine sends the specified message to all subscribers. The +** software bus will read the message ID from the message header to ** determine which pipes should receive the message. ** ** \par Assumptions, External Events, and Notes: -** - This routine will not normally wait for the receiver tasks to +** - This routine will not normally wait for the receiver tasks to ** process the message before returning control to the caller's task. -** - However, if a higher priority task is pending and subscribed to -** this message, that task may get to run before #CFE_SB_SendMsg +** - However, if a higher priority task is pending and subscribed to +** this message, that task may get to run before #CFE_SB_SendMsg ** returns control to the caller. -** - This function tracks and increments the source sequence counter +** - This function tracks and increments the source sequence counter ** of a telemetry message. ** ** \param[in] MsgPtr A pointer to the message to be sent. This must point ** to the first byte of the software bus message header -** (#CFE_SB_Msg_t). +** (#CFE_SB_Msg_t). ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -581,27 +579,27 @@ int32 CFE_SB_UnsubscribeLocal(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId); int32 CFE_SB_SendMsg(CFE_SB_Msg_t *MsgPtr); /*****************************************************************************/ -/** +/** ** \brief Passes a software bus message ** ** \par Description -** This routine sends the specified message to all subscribers. The -** software bus will read the message ID from the message header to +** This routine sends the specified message to all subscribers. The +** software bus will read the message ID from the message header to ** determine which pipes should receive the message. This routine is ** intended to pass messages not generated by the sending application. ** ** \par Assumptions, External Events, and Notes: -** - This routine will not normally wait for the receiver tasks to +** - This routine will not normally wait for the receiver tasks to ** process the message before returning control to the caller's task. -** - However, if a higher priority task is pending and subscribed to -** this message, that task may get to run before #CFE_SB_PassMsg +** - However, if a higher priority task is pending and subscribed to +** this message, that task may get to run before #CFE_SB_PassMsg ** returns control to the caller. ** - Unlike #CFE_SB_SendMsg this routine will preserve the source ** sequence counter in a telemetry message. ** ** \param[in] MsgPtr A pointer to the message to be sent. This must point ** to the first byte of the software bus message header -** (#CFE_SB_Msg_t). +** (#CFE_SB_Msg_t). ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -614,40 +612,38 @@ int32 CFE_SB_SendMsg(CFE_SB_Msg_t *MsgPtr); int32 CFE_SB_PassMsg(CFE_SB_Msg_t *MsgPtr); /*****************************************************************************/ -/** +/** ** \brief Receive a message from a software bus pipe ** ** \par Description -** This routine retrieves the next message from the specified pipe. -** If the pipe is empty, this routine will block until either a new +** This routine retrieves the next message from the specified pipe. +** If the pipe is empty, this routine will block until either a new ** message comes in or the timeout value is reached. ** ** \par Assumptions, External Events, and Notes: ** Note - If an error occurs in this API, the *BufPtr value may be NULL or -** random. Therefore, it is recommended that the return code be tested +** random. Therefore, it is recommended that the return code be tested ** for CFE_SUCCESS before processing the message. ** -** \param[in] BufPtr A pointer to a local variable of type #CFE_SB_MsgPtr_t. -** Typically a caller declares a ptr of type CFE_SB_Msg_t -** (i.e. CFE_SB_Msg_t *Ptr) then gives the address of that -** pointer (&Ptr) as this parmeter. After a successful -** receipt of a message, *BufPtr will point to the first -** byte of the software bus message header. This should be -** used as a read-only pointer (in systems with an MMU, +** \param[in, out] BufPtr A pointer to a local variable of type #CFE_SB_MsgPtr_t. +** Typically a caller declares a ptr of type CFE_SB_Msg_t +** (i.e. CFE_SB_Msg_t *Ptr) then gives the address of that +** pointer (&Ptr) as this parmeter. After a successful +** receipt of a message, *BufPtr will point to the first +** byte of the software bus message header. This should be +** used as a read-only pointer (in systems with an MMU, ** writes to this pointer may cause a memory protection fault). -** The *BufPtr is valid only until the next call to -** CFE_SB_RcvMsg for the same pipe. -** -** \param[in] PipeId The pipe ID of the pipe containing the message to be obtained. +** The *BufPtr is valid only until the next call to +** CFE_SB_RcvMsg for the same pipe. \n *BufPtr is a pointer to the message obtained from the pipe. Valid +** only until the next call to CFE_SB_RcvMsg for the same pipe. +** +** \param[in] PipeId The pipe ID of the pipe containing the message to be obtained. ** ** \param[in] TimeOut The number of milliseconds to wait for a new message if the ** pipe is empty at the time of the call. This can also be set -** to #CFE_SB_POLL for a non-blocking receive or +** to #CFE_SB_POLL for a non-blocking receive or ** #CFE_SB_PEND_FOREVER to wait forever for a message to arrive. ** -** \param[out] *BufPtr A pointer to the message obtained from the pipe. Valid -** only until the next call to CFE_SB_RcvMsg for the same pipe. -** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS ** \retval #CFE_SB_BAD_ARGUMENT \copybrief CFE_SB_BAD_ARGUMENT @@ -667,35 +663,35 @@ int32 CFE_SB_RcvMsg(CFE_SB_MsgPtr_t *BufPtr, */ /*****************************************************************************/ -/** +/** ** \brief Get a buffer pointer to use for "zero copy" SB sends. ** ** \par Description -** This routine can be used to get a pointer to one of the software bus' -** internal memory buffers that are used for sending messages. The caller -** can use this memory buffer to build an SB message, then send it using -** the #CFE_SB_ZeroCopySend function. This interface is more complicated -** than the normal #CFE_SB_ZeroCopySend interface, but it avoids an extra -** copy of the message from the user's memory buffer to the software bus -** internal buffer. The "zero copy" interface can be used to improve +** This routine can be used to get a pointer to one of the software bus' +** internal memory buffers that are used for sending messages. The caller +** can use this memory buffer to build an SB message, then send it using +** the #CFE_SB_ZeroCopySend function. This interface is more complicated +** than the normal #CFE_SB_ZeroCopySend interface, but it avoids an extra +** copy of the message from the user's memory buffer to the software bus +** internal buffer. The "zero copy" interface can be used to improve ** performance in high-rate, high-volume software bus traffic. ** ** \par Assumptions, External Events, and Notes: -** -# The pointer returned by #CFE_SB_ZeroCopyGetPtr is only good for one -** call to #CFE_SB_ZeroCopySend. -** -# Applications should be written as if #CFE_SB_ZeroCopyGetPtr is -** equivalent to a \c malloc() and #CFE_SB_ZeroCopySend is equivalent to +** -# The pointer returned by #CFE_SB_ZeroCopyGetPtr is only good for one +** call to #CFE_SB_ZeroCopySend. +** -# Applications should be written as if #CFE_SB_ZeroCopyGetPtr is +** equivalent to a \c malloc() and #CFE_SB_ZeroCopySend is equivalent to ** a \c free(). -** -# Applications must not de-reference the message pointer (for reading -** or writing) after the call to #CFE_SB_ZeroCopySend. +** -# Applications must not de-reference the message pointer (for reading +** or writing) after the call to #CFE_SB_ZeroCopySend. ** -** \param[in] MsgSize The size of the SB message buffer the caller wants -** (including the SB message header). +** \param[in] MsgSize The size of the SB message buffer the caller wants +** (including the SB message header). ** ** \param[out] BufferHandle A handle that must be supplied when sending or releasing -** in zero copy mode. +** in zero copy mode. ** -** \return A pointer to a memory buffer that can be used to build one SB message +** \return A pointer to a memory buffer that can be used to build one SB message ** for use with #CFE_SB_ZeroCopySend. ** ** \sa #CFE_SB_ZeroCopyReleasePtr, #CFE_SB_ZeroCopySend @@ -704,25 +700,25 @@ CFE_SB_Msg_t *CFE_SB_ZeroCopyGetPtr(uint16 MsgSize, CFE_SB_ZeroCopyHandle_t *BufferHandle); /*****************************************************************************/ -/** +/** ** \brief Release an unused "zero copy" buffer pointer. ** ** \par Description -** This routine can be used to release a pointer to one of the software +** This routine can be used to release a pointer to one of the software ** bus' internal memory buffers. ** ** \par Assumptions, External Events, and Notes: -** -# This function is not needed for normal "zero copy" transfers. It -** is needed only for cleanup when an application gets a pointer using -** #CFE_SB_ZeroCopyGetPtr, but (due to some error condition) never uses -** that pointer for a #CFE_SB_ZeroCopySend +** -# This function is not needed for normal "zero copy" transfers. It +** is needed only for cleanup when an application gets a pointer using +** #CFE_SB_ZeroCopyGetPtr, but (due to some error condition) never uses +** that pointer for a #CFE_SB_ZeroCopySend ** -** \param[in] Ptr2Release A pointer to the SB internal buffer. This must be a -** pointer returned by a call to #CFE_SB_ZeroCopyGetPtr, -** but never used in a call to #CFE_SB_ZeroCopySend. +** \param[in] Ptr2Release A pointer to the SB internal buffer. This must be a +** pointer returned by a call to #CFE_SB_ZeroCopyGetPtr, +** but never used in a call to #CFE_SB_ZeroCopySend. ** -** \param[in] BufferHandle This must be the handle supplied with the pointer -** when #CFE_SB_ZeroCopyGetPtr was called. +** \param[in] BufferHandle This must be the handle supplied with the pointer +** when #CFE_SB_ZeroCopyGetPtr was called. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -734,33 +730,33 @@ int32 CFE_SB_ZeroCopyReleasePtr(CFE_SB_Msg_t *Ptr2Release, CFE_SB_ZeroCopyHandle_t BufferHandle); /*****************************************************************************/ -/** +/** ** \brief Send an SB message in "zero copy" mode. ** ** \par Description -** This routine sends a message that has been created directly in an -** internal SB message buffer by an application (after a call to -** #CFE_SB_ZeroCopyGetPtr). This interface is more complicated than -** the normal #CFE_SB_SendMsg interface, but it avoids an extra copy of -** the message from the user's memory buffer to the software bus -** internal buffer. The "zero copy" interface can be used to improve +** This routine sends a message that has been created directly in an +** internal SB message buffer by an application (after a call to +** #CFE_SB_ZeroCopyGetPtr). This interface is more complicated than +** the normal #CFE_SB_SendMsg interface, but it avoids an extra copy of +** the message from the user's memory buffer to the software bus +** internal buffer. The "zero copy" interface can be used to improve ** performance in high-rate, high-volume software bus traffic. ** ** \par Assumptions, External Events, and Notes: -** -# The pointer returned by #CFE_SB_ZeroCopyGetPtr is only good for -** one call to #CFE_SB_ZeroCopySend. -** -# Callers must not use the same SB message buffer for multiple sends. -** -# Applications should be written as if #CFE_SB_ZeroCopyGetPtr is -** equivalent to a \c malloc() and #CFE_SB_ZeroCopySend is equivalent -** to a \c free(). -** -# Applications must not de-reference the message pointer (for reading -** or writing) after the call to #CFE_SB_ZeroCopySend. -** -# This function tracks and increments the source sequence counter +** -# The pointer returned by #CFE_SB_ZeroCopyGetPtr is only good for +** one call to #CFE_SB_ZeroCopySend. +** -# Callers must not use the same SB message buffer for multiple sends. +** -# Applications should be written as if #CFE_SB_ZeroCopyGetPtr is +** equivalent to a \c malloc() and #CFE_SB_ZeroCopySend is equivalent +** to a \c free(). +** -# Applications must not de-reference the message pointer (for reading +** or writing) after the call to #CFE_SB_ZeroCopySend. +** -# This function tracks and increments the source sequence counter ** of a telemetry message. ** -** \param[in] MsgPtr A pointer to the SB message to be sent. +** \param[in] MsgPtr A pointer to the SB message to be sent. ** -** \param[in] BufferHandle The handle supplied with the #CFE_SB_ZeroCopyGetPtr call. +** \param[in] BufferHandle The handle supplied with the #CFE_SB_ZeroCopyGetPtr call. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -769,41 +765,41 @@ int32 CFE_SB_ZeroCopyReleasePtr(CFE_SB_Msg_t *Ptr2Release, ** \retval #CFE_SB_BUF_ALOC_ERR \copybrief CFE_SB_BUF_ALOC_ERR ** \retval #CFE_SB_BUFFER_INVALID \copybrief CFE_SB_BUFFER_INVALID ** -** \sa #CFE_SB_SendMsg, #CFE_SB_RcvMsg, #CFE_SB_ZeroCopyReleasePtr, #CFE_SB_ZeroCopyGetPtr +** \sa #CFE_SB_SendMsg, #CFE_SB_RcvMsg, #CFE_SB_ZeroCopyReleasePtr, #CFE_SB_ZeroCopyGetPtr **/ int32 CFE_SB_ZeroCopySend(CFE_SB_Msg_t *MsgPtr, CFE_SB_ZeroCopyHandle_t BufferHandle); /*****************************************************************************/ -/** +/** ** \brief Pass an SB message in "zero copy" mode. ** ** \par Description -** This routine sends a message that has been created directly in an -** internal SB message buffer by an application (after a call to -** #CFE_SB_ZeroCopyGetPtr). This interface is more complicated than -** the normal #CFE_SB_SendMsg interface, but it avoids an extra copy of -** the message from the user's memory buffer to the software bus -** internal buffer. The "zero copy" interface can be used to improve -** performance in high-rate, high-volume software bus traffic. This +** This routine sends a message that has been created directly in an +** internal SB message buffer by an application (after a call to +** #CFE_SB_ZeroCopyGetPtr). This interface is more complicated than +** the normal #CFE_SB_SendMsg interface, but it avoids an extra copy of +** the message from the user's memory buffer to the software bus +** internal buffer. The "zero copy" interface can be used to improve +** performance in high-rate, high-volume software bus traffic. This ** version is intended to pass messages not generated by the caller ** (to preserve the source sequence count). ** ** \par Assumptions, External Events, and Notes: -** -# The pointer returned by #CFE_SB_ZeroCopyGetPtr is only good for -** one call to #CFE_SB_ZeroCopySend or #CFE_SB_ZeroCopyPass. -** -# Callers must not use the same SB message buffer for multiple sends. -** -# Applications should be written as if #CFE_SB_ZeroCopyGetPtr is -** equivalent to a \c malloc() and #CFE_SB_ZeroCopyPass is equivalent -** to a \c free(). -** -# Applications must not de-reference the message pointer (for reading -** or writing) after the call to #CFE_SB_ZeroCopyPass. +** -# The pointer returned by #CFE_SB_ZeroCopyGetPtr is only good for +** one call to #CFE_SB_ZeroCopySend or #CFE_SB_ZeroCopyPass. +** -# Callers must not use the same SB message buffer for multiple sends. +** -# Applications should be written as if #CFE_SB_ZeroCopyGetPtr is +** equivalent to a \c malloc() and #CFE_SB_ZeroCopyPass is equivalent +** to a \c free(). +** -# Applications must not de-reference the message pointer (for reading +** or writing) after the call to #CFE_SB_ZeroCopyPass. ** -# Unlike #CFE_SB_ZeroCopySend this routine will preserve the source ** sequence counter in a telemetry message. ** -** \param[in] MsgPtr A pointer to the SB message to be sent. +** \param[in] MsgPtr A pointer to the SB message to be sent. ** -** \param[in] BufferHandle The handle supplied with the #CFE_SB_ZeroCopyGetPtr call. +** \param[in] BufferHandle The handle supplied with the #CFE_SB_ZeroCopyGetPtr call. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -812,7 +808,7 @@ int32 CFE_SB_ZeroCopySend(CFE_SB_Msg_t *MsgPtr, ** \retval #CFE_SB_BUF_ALOC_ERR \copybrief CFE_SB_BUF_ALOC_ERR ** \retval #CFE_SB_BUFFER_INVALID \copybrief CFE_SB_BUFFER_INVALID ** -** \sa #CFE_SB_PassMsg, #CFE_SB_ZeroCopySend, #CFE_SB_ZeroCopyReleasePtr, #CFE_SB_ZeroCopyGetPtr +** \sa #CFE_SB_PassMsg, #CFE_SB_ZeroCopySend, #CFE_SB_ZeroCopyReleasePtr, #CFE_SB_ZeroCopyGetPtr **/ int32 CFE_SB_ZeroCopyPass(CFE_SB_Msg_t *MsgPtr, CFE_SB_ZeroCopyHandle_t BufferHandle); @@ -823,24 +819,24 @@ int32 CFE_SB_ZeroCopyPass(CFE_SB_Msg_t *MsgPtr, */ /*****************************************************************************/ -/** +/** ** \brief Initialize a buffer for a software bus message. ** ** \par Description -** This routine fills in the header information needed to create a +** This routine fills in the header information needed to create a ** valid software bus message. ** ** \par Assumptions, External Events, and Notes: -** None +** None ** -** \param[in] MsgPtr A pointer to the buffer that will contain the message. -** This will point to the first byte of the message header. +** \param[in] MsgPtr A pointer to the buffer that will contain the message. +** This will point to the first byte of the message header. ** The \c void* data type allows the calling routine to use -** any data type when declaring its message buffer. +** any data type when declaring its message buffer. ** ** \param[in] MsgId The message ID to put in the message header. ** -** \param[in] Length The total number of bytes of message data, including the SB +** \param[in] Length The total number of bytes of message data, including the SB ** message header . ** ** \param[in] Clear A flag indicating whether to clear the rest of the message: @@ -848,7 +844,7 @@ int32 CFE_SB_ZeroCopyPass(CFE_SB_Msg_t *MsgPtr, ** \arg false - leave sequence count and packet data unchanged. ** ** \sa #CFE_SB_SetMsgId, #CFE_SB_SetUserDataLength, #CFE_SB_SetTotalMsgLength, -** #CFE_SB_SetMsgTime, #CFE_SB_TimeStampMsg, #CFE_SB_SetCmdCode +** #CFE_SB_SetMsgTime, #CFE_SB_TimeStampMsg, #CFE_SB_SetCmdCode **/ void CFE_SB_InitMsg(void *MsgPtr, CFE_SB_MsgId_t MsgId, @@ -870,7 +866,6 @@ void CFE_SB_InitMsg(void *MsgPtr, ** ** \param[in] MsgId The message ID to put into the message header. ** -** \return The software bus Message ID from the message header. ** ** \sa #CFE_SB_GetMsgId, #CFE_SB_SetUserDataLength, #CFE_SB_SetTotalMsgLength, ** #CFE_SB_SetMsgTime, #CFE_SB_TimeStampMsg, #CFE_SB_SetCmdCode, #CFE_SB_InitMsg @@ -1050,17 +1045,17 @@ int32 CFE_SB_MessageStringSet(char *DestStringPtr, const char *SourceStringPtr, */ /*****************************************************************************/ -/** +/** ** \brief Get a pointer to the user data portion of a software bus message. ** ** \par Description -** This routine returns a pointer to the user data portion of a software -** bus message. SB message header formats can be different for each -** deployment of the cFE. So, applications should use this function and +** This routine returns a pointer to the user data portion of a software +** bus message. SB message header formats can be different for each +** deployment of the cFE. So, applications should use this function and ** avoid hard coding offsets into their SB message buffers. ** ** \par Assumptions, External Events, and Notes: -** None +** None ** ** \param[in] MsgPtr A pointer to the buffer that contains the software bus message. ** @@ -1072,14 +1067,14 @@ int32 CFE_SB_MessageStringSet(char *DestStringPtr, const char *SourceStringPtr, void *CFE_SB_GetUserData(CFE_SB_MsgPtr_t MsgPtr); /*****************************************************************************/ -/** +/** ** \brief Get the message ID of a software bus message. ** ** \par Description ** This routine returns the message ID from a software bus message. ** ** \par Assumptions, External Events, and Notes: -** None +** None ** ** \param[in] MsgPtr A pointer to the buffer that contains the software bus message. ** @@ -1091,17 +1086,17 @@ void *CFE_SB_GetUserData(CFE_SB_MsgPtr_t MsgPtr); CFE_SB_MsgId_t CFE_SB_GetMsgId(const CFE_SB_Msg_t *MsgPtr); /*****************************************************************************/ -/** +/** ** \brief Gets the length of user data in a software bus message. ** ** \par Description ** This routine returns the size of the user data in a software bus message. ** ** \par Assumptions, External Events, and Notes: -** None +** None ** ** \param[in] MsgPtr A pointer to the buffer that contains the software bus message. -** This must point to the first byte of the message header. +** This must point to the first byte of the message header. ** ** \return The size (in bytes) of the user data in the software bus message. ** @@ -1111,15 +1106,15 @@ CFE_SB_MsgId_t CFE_SB_GetMsgId(const CFE_SB_Msg_t *MsgPtr); uint16 CFE_SB_GetUserDataLength(const CFE_SB_Msg_t *MsgPtr); /*****************************************************************************/ -/** +/** ** \brief Gets the total length of a software bus message. ** ** \par Description -** This routine returns the total size of the software bus message. +** This routine returns the total size of the software bus message. ** ** \par Assumptions, External Events, and Notes: ** - For the CCSDS implementation of this API, the size is derived from -** the message header. +** the message header. ** ** \param[in] MsgPtr A pointer to the buffer that contains the software bus message. ** This must point to the first byte of the message header. @@ -1156,21 +1151,21 @@ uint16 CFE_SB_GetTotalMsgLength(const CFE_SB_Msg_t *MsgPtr); uint16 CFE_SB_GetCmdCode(CFE_SB_MsgPtr_t MsgPtr); /*****************************************************************************/ -/** +/** ** \brief Gets the time field from a software bus message. ** ** \par Description -** This routine gets the time from a software bus message. +** This routine gets the time from a software bus message. ** ** \par Assumptions, External Events, and Notes: -** - If the underlying implementation of software bus messages does not -** include a time field, then this routine will return a zero time. +** - If the underlying implementation of software bus messages does not +** include a time field, then this routine will return a zero time. ** - Note default implementation of command messages do not have a time field. ** ** \param[in] MsgPtr A pointer to the buffer that contains the software bus message. -** This must point to the first byte of the message header. +** This must point to the first byte of the message header. ** -** \return The system time included in the software bus message header (if present), +** \return The system time included in the software bus message header (if present), ** otherwise, returns a time value of zero. ** ** \sa #CFE_SB_GetUserData, #CFE_SB_GetMsgId, #CFE_SB_GetUserDataLength, #CFE_SB_GetTotalMsgLength, @@ -1256,20 +1251,20 @@ int32 CFE_SB_MessageStringGet(char *DestStringPtr, const char *SourceStringPtr, */ /*****************************************************************************/ -/** +/** ** \brief Gets the checksum field from a software bus message. ** ** \par Description -** This routine gets the checksum (or other message integrity check -** value) from a software bus message. The contents and location of -** this field will depend on the underlying implementation of software -** bus messages. It may be a checksum, a CRC, or some other algorithm. -** Users should not call this function as part of a message integrity -** check (call #CFE_SB_ValidateChecksum instead). +** This routine gets the checksum (or other message integrity check +** value) from a software bus message. The contents and location of +** this field will depend on the underlying implementation of software +** bus messages. It may be a checksum, a CRC, or some other algorithm. +** Users should not call this function as part of a message integrity +** check (call #CFE_SB_ValidateChecksum instead). ** ** \par Assumptions, External Events, and Notes: -** - If the underlying implementation of software bus messages does not -** include a checksum field, then this routine will return a zero. +** - If the underlying implementation of software bus messages does not +** include a checksum field, then this routine will return a zero. ** ** \param[in] MsgPtr A pointer to the buffer that contains the software bus message. ** This must point to the first byte of the message header. @@ -1279,24 +1274,24 @@ int32 CFE_SB_MessageStringGet(char *DestStringPtr, const char *SourceStringPtr, ** ** \sa #CFE_SB_GetUserData, #CFE_SB_GetMsgId, #CFE_SB_GetUserDataLength, #CFE_SB_GetTotalMsgLength, ** #CFE_SB_GetMsgTime, #CFE_SB_GetCmdCode, #CFE_SB_GetChecksum -** #CFE_SB_ValidateChecksum, #CFE_SB_GenerateChecksum +** #CFE_SB_ValidateChecksum, #CFE_SB_GenerateChecksum **/ uint16 CFE_SB_GetChecksum(CFE_SB_MsgPtr_t MsgPtr); /*****************************************************************************/ -/** +/** ** \brief Calculates and sets the checksum of a software bus message ** ** \par Description -** This routine calculates the checksum of a software bus message according -** to an implementation-defined algorithm. Then, it sets the checksum field -** in the message with the calculated value. The contents and location of -** this field will depend on the underlying implementation of software bus -** messages. It may be a checksum, a CRC, or some other algorithm. +** This routine calculates the checksum of a software bus message according +** to an implementation-defined algorithm. Then, it sets the checksum field +** in the message with the calculated value. The contents and location of +** this field will depend on the underlying implementation of software bus +** messages. It may be a checksum, a CRC, or some other algorithm. ** ** \par Assumptions, External Events, and Notes: -** - If the underlying implementation of software bus messages does not -** include a checksum field, then this routine will do nothing. +** - If the underlying implementation of software bus messages does not +** include a checksum field, then this routine will do nothing. ** ** \param[in] MsgPtr A pointer to the buffer that contains the software bus message. ** This must point to the first byte of the message header. @@ -1306,19 +1301,19 @@ uint16 CFE_SB_GetChecksum(CFE_SB_MsgPtr_t MsgPtr); void CFE_SB_GenerateChecksum(CFE_SB_MsgPtr_t MsgPtr); /*****************************************************************************/ -/** +/** ** \brief Validates the checksum of a software bus message. ** ** \par Description -** This routine calculates the expected checksum of a software bus message -** according to an implementation-defined algorithm. Then, it checks the -** calculated value against the value in the message's checksum. If the -** checksums do not match, this routine will generate an event message -** reporting the error. +** This routine calculates the expected checksum of a software bus message +** according to an implementation-defined algorithm. Then, it checks the +** calculated value against the value in the message's checksum. If the +** checksums do not match, this routine will generate an event message +** reporting the error. ** ** \par Assumptions, External Events, and Notes: -** - If the underlying implementation of software bus messages does not -** include a checksum field, then this routine will always return \c true. +** - If the underlying implementation of software bus messages does not +** include a checksum field, then this routine will always return \c true. ** ** \param[in] MsgPtr A pointer to the buffer that contains the software bus message. ** This must point to the first byte of the message header. diff --git a/fsw/cfe-core/src/inc/cfe_sb_msg.h b/fsw/cfe-core/src/inc/cfe_sb_msg.h index c43f5b838..d7a7d0fda 100644 --- a/fsw/cfe-core/src/inc/cfe_sb_msg.h +++ b/fsw/cfe-core/src/inc/cfe_sb_msg.h @@ -367,7 +367,8 @@ /** \cfesbcmd Enable Subscription Reporting Command ** -** \par This command will enable subscription reporting and is intended to +** \par Description +** This command will enable subscription reporting and is intended to ** be used only by the CFS SBN (Software Bus Networking) Application. ** It is not intended to be sent from the ground or used by operations. ** When subscription reporting is enabled, SB will generate @@ -399,7 +400,8 @@ /** \cfesbcmd Disable Subscription Reporting Command ** -** \par This command will disable subscription reporting and is intended to +** \par Description +** This command will disable subscription reporting and is intended to ** be used only by the CFS SBN (Software Bus Networking) Application. ** It is not intended to be sent from the ground or used by operations. ** When subscription reporting is enabled, SB will generate diff --git a/fsw/cfe-core/src/inc/cfe_tbl.h b/fsw/cfe-core/src/inc/cfe_tbl.h index ab0adc49b..88fecd553 100644 --- a/fsw/cfe-core/src/inc/cfe_tbl.h +++ b/fsw/cfe-core/src/inc/cfe_tbl.h @@ -165,9 +165,10 @@ typedef struct ** their own tables. An application should create any table(s) and provide the handle(s) ** to the interrupt service routine. ** -** \param[in] TblHandlePtr a pointer to a #CFE_TBL_Handle_t type variable that will be assigned the +** \param[in, out] TblHandlePtr a pointer to a #CFE_TBL_Handle_t type variable that will be assigned the ** table's handle. The table handle is required for other API calls when -** accessing the data contained in the table. +** accessing the data contained in the table. *TblHandlePtr is the handle used to identify table to cFE when performing Table operations. +** This value is returned at the address specified by TblHandlePtr. ** ** \param[in] Name The application-specific name. This name will be combined with the name of the ** application to produce a processor specific name of the form @@ -264,9 +265,6 @@ typedef struct ** will be executed in the Application's context so that Event Messages describing the ** validation failure are possible from within the function. ** -** \param[out] *TblHandlePtr Handle used to identify table to cFE when performing Table operations. -** This value is returned at the address specified by TblHandlePtr. -** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS ** \retval #CFE_TBL_INFO_RECOVERED_TBL \copybrief CFE_TBL_INFO_RECOVERED_TBL @@ -301,10 +299,11 @@ int32 CFE_TBL_Register( CFE_TBL_Handle_t *TblHandlePtr, /* Ret ** \par Assumptions, External Events, and Notes: ** None ** -** \param[in] TblHandlePtr A pointer to a #CFE_TBL_Handle_t type variable +** \param[in, out] TblHandlePtr A pointer to a #CFE_TBL_Handle_t type variable ** that will be assigned the table's handle. The ** table handle is required for other API calls -** when accessing the data contained in the table. +** when accessing the data contained in the table. *TblHandlePtr is the handle used to identify table to cFE when performing Table operations. +** This value is returned at the address specified by TblHandlePtr. ** ** \param[in] TblName The processor specific name of the table. It is important to note ** that the processor specific table name is different from the table @@ -314,9 +313,6 @@ int32 CFE_TBL_Register( CFE_TBL_Handle_t *TblHandlePtr, /* Ret ** An example of this would be "ACS.TamParams" for a table called "TamParams" ** that was registered by the application called "ACS". ** -** \param[out] *TblHandlePtr Handle used to identify table to cFE when performing Table operations. -** This value is returned at the address specified by TblHandlePtr. -** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS ** \retval #CFE_TBL_ERR_HANDLES_FULL \copybrief CFE_TBL_ERR_HANDLES_FULL @@ -607,15 +603,13 @@ int32 CFE_TBL_Modified( CFE_TBL_Handle_t TblHandle ); ** This pointer mush be released with the #CFE_TBL_ReleaseAddress API before ** the table can be loaded with data. ** -** \param[in] TblPtr The address of a pointer that will be loaded with the address of +** \param[in, out] TblPtr The address of a pointer that will be loaded with the address of ** the first byte of the table. This pointer can then be typecast -** by the calling application to the appropriate table data structure. +** by the calling application to the appropriate table data structure. *TblPtr is the address of the first byte of data associated with the specified table. ** ** \param[in] TblHandle Handle, previously obtained from #CFE_TBL_Register or #CFE_TBL_Share, that ** identifies the Table whose address is to be returned. ** -** \param[out] *TblPtr Address of the first byte of data associated with the specified table. -** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS ** \retval #CFE_TBL_INFO_UPDATED \copybrief CFE_TBL_INFO_UPDATED @@ -692,17 +686,15 @@ int32 CFE_TBL_ReleaseAddress( CFE_TBL_Handle_t TblHandle ); ** This pointer mush be released with the #CFE_TBL_ReleaseAddress API before ** the table can be loaded with data. ** -** \param[in] TblPtrs Array of Pointers to variables that calling Application -** wishes to hold the start addresses of the Tables. +** \param[in, out] TblPtrs Array of Pointers to variables that calling Application +** wishes to hold the start addresses of the Tables. *TblPtrs is an array of addresses of the first byte of data associated with the +** specified tables. ** ** \param[in] NumTables Size of TblPtrs and TblHandles arrays. ** ** \param[in] TblHandles Array of Table Handles, previously obtained from #CFE_TBL_Register or #CFE_TBL_Share, ** of those tables whose start addresses are to be obtained. ** -** \param[out] *TblPtrs Array of addresses of the first byte of data associated with the -** specified tables. -** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS ** \retval #CFE_TBL_INFO_UPDATED \copybrief CFE_TBL_INFO_UPDATED @@ -807,8 +799,9 @@ int32 CFE_TBL_GetStatus( CFE_TBL_Handle_t TblHandle ); ** \par Assumptions, External Events, and Notes: ** None ** -** \param[in] TblInfoPtr A pointer to a CFE_TBL_Info_t data structure that is to be populated -** with table characteristics and information. +** \param[in, out] TblInfoPtr A pointer to a CFE_TBL_Info_t data structure that is to be populated +** with table characteristics and information. *TblInfoPtr is the description of the tables characteristics and registry information stored in +** the #CFE_TBL_Info_t data structure format. ** ** \param[in] TblName The processor specific name of the table. It is important to note ** that the processor specific table name is different from the table @@ -818,9 +811,6 @@ int32 CFE_TBL_GetStatus( CFE_TBL_Handle_t TblHandle ); ** An example of this would be "ACS.TamParams" for a table called "TamParams" ** that was registered by the application called "ACS". ** -** \param[out] *TblInfoPtr Description of the tables characteristics and registry information stored in -** the #CFE_TBL_Info_t data structure format. -** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS ** \retval #CFE_TBL_ERR_INVALID_NAME \copybrief CFE_TBL_ERR_INVALID_NAME diff --git a/fsw/cfe-core/src/inc/cfe_tbl_events.h b/fsw/cfe-core/src/inc/cfe_tbl_events.h index 8906b5d08..e1b56fc48 100644 --- a/fsw/cfe-core/src/inc/cfe_tbl_events.h +++ b/fsw/cfe-core/src/inc/cfe_tbl_events.h @@ -66,6 +66,8 @@ ** Task completes its Initialization. **/ #define CFE_TBL_INIT_INF_EID 1 +/** \} */ + /** \name Command Response Informational Event Message IDs */ /** \{ */ @@ -841,6 +843,7 @@ #define CFE_TBL_FAIL_NOTIFY_SEND_ERR_EID 89 /** \} */ + /** \name API Informational Event Message IDs */ /** \{ */ @@ -895,7 +898,6 @@ /** \} */ - /** \name API Error Event Message IDs */ /** \{ */ /** \brief '\%s Failed to Register '\%s', Status=0x\%08X' @@ -1100,7 +1102,6 @@ /** \} */ - #endif /* _cfe_tbl_events_ */ /************************/ diff --git a/fsw/cfe-core/src/inc/cfe_time.h b/fsw/cfe-core/src/inc/cfe_time.h index 43ff740cd..9893dd939 100644 --- a/fsw/cfe-core/src/inc/cfe_time.h +++ b/fsw/cfe-core/src/inc/cfe_time.h @@ -876,13 +876,11 @@ int32 CFE_TIME_UnregisterSynchCallback(CFE_TIME_SynchCallbackPtr_t CallbackFunc ** the maximum amount of time represented by a CFE_TIME_SysTime ** structure is approximately 136 years. ** -** \param[in] PrintBuffer Pointer to a character array of at least -** #CFE_TIME_PRINTED_STRING_SIZE characters in length +** \param[in, out] PrintBuffer Pointer to a character array of at least +** #CFE_TIME_PRINTED_STRING_SIZE characters in length. *PrintBuffer is the time as a character string as described above. ** ** \param[in] TimeToPrint The time to print into the character array. ** -** \param[out] *PrintBuffer The time as a character string as described above. -** ******************************************************************************/ void CFE_TIME_Print(char *PrintBuffer, CFE_TIME_SysTime_t TimeToPrint); diff --git a/fsw/cfe-core/src/inc/private/cfe_private.h b/fsw/cfe-core/src/inc/private/cfe_private.h index 1400e20af..11f38014b 100644 --- a/fsw/cfe-core/src/inc/private/cfe_private.h +++ b/fsw/cfe-core/src/inc/private/cfe_private.h @@ -52,7 +52,7 @@ ** \par Assumptions, External Events, and Notes: ** None ** -** \retval None +** ******************************************************************************/ extern void CFE_TIME_TaskMain(void); @@ -66,7 +66,7 @@ extern void CFE_TIME_TaskMain(void); ** \par Assumptions, External Events, and Notes: ** None ** -** \retval None +** ******************************************************************************/ extern void CFE_SB_TaskMain(void); @@ -80,7 +80,7 @@ extern void CFE_SB_TaskMain(void); ** \par Assumptions, External Events, and Notes: ** None ** -** \retval None +** ******************************************************************************/ extern void CFE_EVS_TaskMain(void); @@ -94,7 +94,7 @@ extern void CFE_EVS_TaskMain(void); ** \par Assumptions, External Events, and Notes: ** None ** -** \retval None +** ******************************************************************************/ extern void CFE_ES_TaskMain(void); @@ -110,7 +110,7 @@ extern void CFE_ES_TaskMain(void); ** \par Assumptions, External Events, and Notes: ** None ** -** \retval None +** ******************************************************************************/ extern void CFE_TBL_TaskMain(void); @@ -290,7 +290,7 @@ extern int32 CFE_TIME_CleanUpApp(uint32 AppId); ** -# This function assumes input parameters are error free and have met size/value restrictions. ** -# The calling function is responsible for issuing any event messages associated with errors. ** -** \param[in] HandlePtr Pointer Application's variable that will contain the CDS Memory Block Handle. +** \param[in, out] HandlePtr Pointer Application's variable that will contain the CDS Memory Block Handle. *HandlePtr is the handle of the CDS block that can be used in #CFE_ES_CopyToCDS and #CFE_ES_RestoreFromCDS. ** ** \param[in] BlockSize The number of bytes needed in the CDS. ** @@ -299,7 +299,6 @@ extern int32 CFE_TIME_CleanUpApp(uint32 AppId); ** ** \param[in] CriticalTbl Indicates whether the CDS is to be used as a Critical Table or not ** -** \param[out] *HandlePtr The handle of the CDS block that can be used in #CFE_ES_CopyToCDS and #CFE_ES_RestoreFromCDS. ** ** \return See return codes for #CFE_ES_RegisterCDS ** diff --git a/fsw/cfe-core/src/sb/cfe_sb_priv.h b/fsw/cfe-core/src/sb/cfe_sb_priv.h index c70dcec82..86201fd47 100644 --- a/fsw/cfe-core/src/sb/cfe_sb_priv.h +++ b/fsw/cfe-core/src/sb/cfe_sb_priv.h @@ -401,33 +401,31 @@ int32 CFE_SB_RemoveDest(CFE_SB_RouteEntry_t *RouteEntry, CFE_SB_DestinationD_t * /*****************************************************************************/ -/** +/** ** \brief Get the size of a software bus message header. ** ** \par Description -** This routine returns the number of bytes in a software bus message header. -** This can be used for sizing buffers that need to store SB messages. SB -** message header formats can be different for each deployment of the cFE. -** So, applications should use this function and avoid hard coding their buffer +** This routine returns the number of bytes in a software bus message header. +** This can be used for sizing buffers that need to store SB messages. SB +** message header formats can be different for each deployment of the cFE. +** So, applications should use this function and avoid hard coding their buffer ** sizes. ** ** \par Assumptions, External Events, and Notes: -** - For statically defined messages, a function call will not work. The -** macros #CFE_SB_CMD_HDR_SIZE and #CFE_SB_TLM_HDR_SIZE are available for use -** in static message buffer sizing or structure definitions. +** - For statically defined messages, a function call will not work. The +** macros #CFE_SB_CMD_HDR_SIZE and #CFE_SB_TLM_HDR_SIZE are available for use +** in static message buffer sizing or structure definitions. ** -** \param[in] *MsgPtr The message ID to calculate header size for. The size of the message -** header may depend on the MsgId in some implementations. For example, -** if SB messages are implemented as CCSDS packets, the size of the header +** \param[in] *MsgPtr The message ID to calculate header size for. The size of the message +** header may depend on the MsgId in some implementations. For example, +** if SB messages are implemented as CCSDS packets, the size of the header ** is different for command vs. telemetry packets. ** -** \returns -** \retstmt The number of bytes in the software bus message header for -** messages with the given \c MsgId. endstmt -** \endreturns +** \returns The number of bytes in the software bus message header for +** messages with the given \c MsgId. ** ** \sa #CFE_SB_GetUserData, #CFE_SB_GetMsgId, #CFE_SB_GetUserDataLength, #CFE_SB_GetTotalMsgLength, -** #CFE_SB_GetMsgTime, #CFE_SB_GetCmdCode, #CFE_SB_GetChecksum +** #CFE_SB_GetMsgTime, #CFE_SB_GetCmdCode, #CFE_SB_GetChecksum **/ uint16 CFE_SB_MsgHdrSize(const CFE_SB_Msg_t *MsgPtr); diff --git a/fsw/cfe-core/src/tbl/cfe_tbl_internal.h b/fsw/cfe-core/src/tbl/cfe_tbl_internal.h index b09bb54a3..42f788cee 100644 --- a/fsw/cfe-core/src/tbl/cfe_tbl_internal.h +++ b/fsw/cfe-core/src/tbl/cfe_tbl_internal.h @@ -59,9 +59,8 @@ ** \par Assumptions, External Events, and Notes: ** None ** -** \param[in] AppIdPtr Pointer to value that will hold AppID on return. +** \param[in, out] AppIdPtr Pointer to value that will hold AppID on return. *AppIdPtr is the AppID as obtained from #CFE_ES_GetAppID ** -** \param[out] *AppIdPtr The AppID as obtained from #CFE_ES_GetAppID ** ** \retval #CFE_SUCCESS \copydoc CFE_SUCCESS ** \retval #CFE_TBL_ERR_BAD_APP_ID \copydoc CFE_TBL_ERR_BAD_APP_ID @@ -106,9 +105,8 @@ int32 CFE_TBL_ValidateHandle(CFE_TBL_Handle_t TblHandle); ** ** \param[in] TblHandle Handle of table whose access is desired. ** -** \param[in] AppIdPtr Pointer to value that will hold AppID on return. +** \param[in, out] AppIdPtr Pointer to value that will hold AppID on return. *AppIdPtr is the AppID as obtained from #CFE_ES_GetAppID ** -** \param[out] *AppIdPtr The AppID as obtained from #CFE_ES_GetAppID ** ** \retval #CFE_SUCCESS \copydoc CFE_SUCCESS ** \retval #CFE_TBL_ERR_BAD_APP_ID \copydoc CFE_TBL_ERR_BAD_APP_ID @@ -179,11 +177,10 @@ int32 CFE_TBL_RemoveAccessLink(CFE_TBL_Handle_t TblHandle); ** this function would return #CFE_TBL_ERR_UNREGISTERED. ** -# ThisAppId parameter is assumed to be validated. ** -** \param[in] TblPtr Pointer to pointer that will hold address of data upon return. +** \param[in, out] TblPtr Pointer to pointer that will hold address of data upon return. *TblPtr is the address of the Table Data. ** \param[in] TblHandle Handle of Table whose address is needed. ** \param[in] ThisAppId AppID of application making the address request. ** -** \param[out] *TblPtr Address of Table Data. ** ** \retval #CFE_SUCCESS \copydoc CFE_SUCCESS ** \retval #CFE_TBL_ERR_INVALID_HANDLE \copydoc CFE_TBL_ERR_INVALID_HANDLE @@ -275,17 +272,16 @@ CFE_TBL_Handle_t CFE_TBL_FindFreeHandle(void); ** \par Assumptions, External Events, and Notes: ** Note: AppName portion will be truncated to OS_MAX_API_NAME. ** -** \param[in] FullTblName pointer to character buffer of #CFE_TBL_MAX_FULL_NAME_LEN size -** that will be filled with the processor specific Table Name. +** \param[in, out] FullTblName pointer to character buffer of #CFE_TBL_MAX_FULL_NAME_LEN size +** that will be filled with the processor specific Table Name. *FullTblName is the processor specific Table Name of the form "AppName.TblName". ** ** \param[in] TblName pointer to character string containing the Application's local name for ** the Table. ** ** \param[in] ThisAppId the Application ID of the Application making the call. ** -** \param[out] *FullTblName processor specific Table Name of the form "AppName.TblName". ** -** \retval None +** ******************************************************************************/ void CFE_TBL_FormTableName(char *FullTblName, const char *TblName, uint32 ThisAppId); @@ -338,8 +334,8 @@ int32 CFE_TBL_UnlockRegistry(void); ** -# This function assumes the TblHandle and MinBufferSize values ** are legitimate. ** -** \param[in] WorkingBufferPtr Pointer to variable that will contain the -** address of the first byte of the working buffer +** \param[in, out] WorkingBufferPtr Pointer to variable that will contain the +** address of the first byte of the working buffer. *WorkingBufferPtr is the address of the first byte of the working buffer ** ** \param[in] RegRecPtr Pointer to Table Registry Entry for Table for whom ** a working buffer is to be obtained @@ -348,7 +344,6 @@ int32 CFE_TBL_UnlockRegistry(void); ** function is being called by a user Application (true) ** or by the Table Services Application (false) ** -** \param[out] *WorkingBufferPtr Address of first byte of working buffer ** ** \retval #CFE_SUCCESS \copydoc CFE_SUCCESS ** \retval #CFE_TBL_ERR_NO_BUFFER_AVAIL \copydoc CFE_TBL_ERR_NO_BUFFER_AVAIL @@ -459,18 +454,16 @@ void CFE_TBL_NotifyTblUsersOfUpdate( CFE_TBL_RegistryRec_t *RegRecPtr ); ** ** \param[in] FileDescriptor File Descriptor, as provided by OS_fopen ** -** \param[in] StdFileHeaderPtr Pointer to buffer to be filled with the contents -** of the file's standard cFE Header +** \param[in, out] StdFileHeaderPtr Pointer to buffer to be filled with the contents +** of the file's standard cFE Header. *StdFileHeaderPtr is the contents of the standard cFE File Header ** -** \param[in] TblFileHeaderPtr Pointer to buffer to be filled with the contents -** of the file's standard cFE Table Header +** \param[in, out] TblFileHeaderPtr Pointer to buffer to be filled with the contents +** of the file's standard cFE Table Header. *TblFileHeaderPtr is the contents of the standard cFE Table File Header ** ** \param[in] LoadFilename Pointer to character string containing full path ** and filename of table image to be loaded ** -** \param[out] *StdFileHeaderPtr Contents of standard cFE File Header ** -** \param[out] *TblFileHeaderPtr Contents of standard cFE Table File Header ** ** \retval #CFE_SUCCESS \copydoc CFE_SUCCESS ** \retval #CFE_TBL_ERR_NO_STD_HEADER \copydoc CFE_TBL_ERR_NO_STD_HEADER @@ -513,10 +506,8 @@ void CFE_TBL_InitRegistryRecord (CFE_TBL_RegistryRec_t *RegRecPtr); ** \par Assumptions, External Events, and Notes: ** None ** -** \param[in] HdrPtr Pointer to table header that needs to be swapped. +** \param[in, out] HdrPtr Pointer to table header that needs to be swapped. *HdrPtr provides the swapped header ** -** \param[out] *HdrPtr The swapped header -** ** ******************************************************************************/ void CFE_TBL_ByteSwapTblHeader(CFE_TBL_File_Hdr_t *HdrPtr); @@ -536,15 +527,14 @@ void CFE_TBL_ByteSwapTblHeader(CFE_TBL_File_Hdr_t *HdrPtr); ** \par Assumptions, External Events, and Notes: ** None ** -** \param[in] **CritRegRecPtr Pointer to a pointer that should be initialized with +** \param[in, out] **CritRegRecPtr Pointer to a pointer that should be initialized with ** the start address of the located Critical Table Registry -** Record. +** Record. *CritRegRecPtr is the pointer to the start address of the located Critical +** Table Registry Record. \c NULL if the record is not +** found. ** ** \param[in] CDSHandleToFind CDS Handle to be located in Critical Table Registry. ** -** \param[out] *CritRegRecPtr Pointer to the start address of the located Critical -** Table Registry Record. \c NULL if the record is not -** found. ** ******************************************************************************/ void CFE_TBL_FindCriticalTblInfo(CFE_TBL_CritRegRec_t **CritRegRecPtr, CFE_ES_CDSHandle_t CDSHandleToFind); @@ -601,9 +591,7 @@ int32 CFE_TBL_SendNotificationMsg(CFE_TBL_RegistryRec_t *RegRecPtr); ** \par Assumptions, External Events, and Notes: ** None ** -** \param[in] Uint32ToSwapPtr Pointer to uint32 value to be swapped. -** -** \param[out] *Uint32ToSwapPtr The swapped uint32 value +** \param[in, out] Uint32ToSwapPtr Pointer to uint32 value to be swapped. *Uint32ToSwapPtr is the swapped uint32 value ** ** ******************************************************************************/ diff --git a/fsw/cfe-core/src/tbl/cfe_tbl_task.h b/fsw/cfe-core/src/tbl/cfe_tbl_task.h index 44d9e2135..6cd8e5c3d 100644 --- a/fsw/cfe-core/src/tbl/cfe_tbl_task.h +++ b/fsw/cfe-core/src/tbl/cfe_tbl_task.h @@ -402,7 +402,7 @@ int32 CFE_TBL_TaskInit(void); ** ** \param[in] MessagePtr a pointer to the message received from the command pipe ** -** \retval None +** ******************************************************************************/ void CFE_TBL_TaskPipe(CFE_SB_Msg_t *MessagePtr); @@ -416,7 +416,7 @@ void CFE_TBL_TaskPipe(CFE_SB_Msg_t *MessagePtr); ** \par Assumptions, External Events, and Notes: ** None ** -** \retval None +** ******************************************************************************/ void CFE_TBL_InitData(void); diff --git a/fsw/cfe-core/src/tbl/cfe_tbl_task_cmds.h b/fsw/cfe-core/src/tbl/cfe_tbl_task_cmds.h index c71e28810..6ffec67d7 100644 --- a/fsw/cfe-core/src/tbl/cfe_tbl_task_cmds.h +++ b/fsw/cfe-core/src/tbl/cfe_tbl_task_cmds.h @@ -91,7 +91,7 @@ typedef struct { ** \par Assumptions, External Events, and Notes: ** None ** -** \retval None +** ******************************************************************************/ extern void CFE_TBL_GetHkData(void); @@ -108,7 +108,7 @@ extern void CFE_TBL_GetHkData(void); ** #CFE_TBL_TaskData_t::HkTlmTblRegIndex is assumed to be a valid index into ** the Table Registry. ** -** \retval None +** ******************************************************************************/ extern void CFE_TBL_GetTblRegData(void); @@ -120,9 +120,9 @@ extern void CFE_TBL_GetTblRegData(void); ** Constructs a Housekeeping Packet (#CFE_TBL_HousekeepingTlm_t) from task data and sends it out ** ** \par Assumptions, External Events, and Notes: -** The message pointed to by MessagePtr has been identified as a Housekeeping Request Message +** The message pointed to by data has been identified as a Housekeeping Request Message ** -** \param[in] MessagePtr points to the message received via command pipe that needs processing +** \param[in] data points to the message received via command pipe that needs processing ** ** \retval #CFE_TBL_DONT_INC_CTR \copydoc CFE_TBL_DONT_INC_CTR ******************************************************************************/ @@ -136,9 +136,9 @@ int32 CFE_TBL_HousekeepingCmd(const CCSDS_CommandPacket_t *data); ** Responds to the NOOP command by issuing an Event Message ** ** \par Assumptions, External Events, and Notes: -** The message pointed to by MessagePtr has been identified as a NO OP Command Message +** The message pointed to by data has been identified as a NO OP Command Message ** -** \param[in] MessagePtr points to the message received via command pipe that needs processing +** \param[in] data points to the message received via command pipe that needs processing ** ** \retval #CFE_TBL_INC_ERR_CTR \copydoc CFE_TBL_INC_ERR_CTR ** \retval #CFE_TBL_INC_CMD_CTR \copydoc CFE_TBL_INC_CMD_CTR @@ -153,9 +153,9 @@ int32 CFE_TBL_NoopCmd(const CFE_TBL_Noop_t *data); ** Resets command counters and validation request counters ** ** \par Assumptions, External Events, and Notes: -** The message pointed to by MessagePtr has been identified as a Reset Counters Command Message +** The message pointed to by data has been identified as a Reset Counters Command Message ** -** \param[in] MessagePtr points to the message received via command pipe that needs processing +** \param[in] data points to the message received via command pipe that needs processing ** ** \retval #CFE_TBL_DONT_INC_CTR \copydoc CFE_TBL_DONT_INC_CTR ******************************************************************************/ @@ -170,9 +170,9 @@ int32 CFE_TBL_ResetCountersCmd(const CFE_TBL_ResetCounters_t *data); ** a buffer that is associated with the table specified within the file header. ** ** \par Assumptions, External Events, and Notes: -** The message pointed to by MessagePtr has been identified as a Load Table Command Message +** The message pointed to by data has been identified as a Load Table Command Message ** -** \param[in] MessagePtr points to the message received via command pipe that needs processing +** \param[in] data points to the message received via command pipe that needs processing ** ** \retval #CFE_TBL_INC_ERR_CTR \copydoc CFE_TBL_INC_ERR_CTR ** \retval #CFE_TBL_INC_CMD_CTR \copydoc CFE_TBL_INC_CMD_CTR @@ -188,9 +188,9 @@ int32 CFE_TBL_LoadCmd(const CFE_TBL_Load_t *data); ** the data contents to the command message specified file. ** ** \par Assumptions, External Events, and Notes: -** The message pointed to by MessagePtr has been identified as a Dump Table Command Message +** The message pointed to by data has been identified as a Dump Table Command Message ** -** \param[in] MessagePtr points to the message received via command pipe that needs processing +** \param[in] data points to the message received via command pipe that needs processing ** ** \retval #CFE_TBL_INC_ERR_CTR \copydoc CFE_TBL_INC_ERR_CTR ** \retval #CFE_TBL_INC_CMD_CTR \copydoc CFE_TBL_INC_CMD_CTR @@ -207,9 +207,9 @@ int32 CFE_TBL_DumpCmd(const CFE_TBL_Dump_t *data); ** of the buffer's contents is required. ** ** \par Assumptions, External Events, and Notes: -** The message pointed to by MessagePtr has been identified as a Validate Table Command Message +** The message pointed to by data has been identified as a Validate Table Command Message ** -** \param[in] MessagePtr points to the message received via command pipe that needs processing +** \param[in] data points to the message received via command pipe that needs processing ** ** \retval #CFE_TBL_INC_ERR_CTR \copydoc CFE_TBL_INC_ERR_CTR ** \retval #CFE_TBL_INC_CMD_CTR \copydoc CFE_TBL_INC_CMD_CTR @@ -225,9 +225,9 @@ int32 CFE_TBL_ValidateCmd(const CFE_TBL_Validate_t *data); ** be used. ** ** \par Assumptions, External Events, and Notes: -** The message pointed to by MessagePtr has been identified as an Activate Table Command Message +** The message pointed to by data has been identified as an Activate Table Command Message ** -** \param[in] MessagePtr points to the message received via command pipe that needs processing +** \param[in] data points to the message received via command pipe that needs processing ** ** \retval #CFE_TBL_INC_ERR_CTR \copydoc CFE_TBL_INC_ERR_CTR ** \retval #CFE_TBL_INC_CMD_CTR \copydoc CFE_TBL_INC_CMD_CTR @@ -242,9 +242,9 @@ int32 CFE_TBL_ActivateCmd(const CFE_TBL_Activate_t *data); ** Copies the contents of the Table Registry to a command message specified file. ** ** \par Assumptions, External Events, and Notes: -** The message pointed to by MessagePtr has been identified as a Dump Table Registry Command Message +** The message pointed to by data has been identified as a Dump Table Registry Command Message ** -** \param[in] MessagePtr points to the message received via command pipe that needs processing +** \param[in] data points to the message received via command pipe that needs processing ** ** \retval #CFE_TBL_INC_ERR_CTR \copydoc CFE_TBL_INC_ERR_CTR ** \retval #CFE_TBL_INC_CMD_CTR \copydoc CFE_TBL_INC_CMD_CTR @@ -260,9 +260,9 @@ int32 CFE_TBL_DumpRegistryCmd(const CFE_TBL_DumpRegistry_t *data); ** a message that is sent out. ** ** \par Assumptions, External Events, and Notes: -** The message pointed to by MessagePtr has been identified as a Telemeter Table Registry Entry Command Message +** The message pointed to by data has been identified as a Telemeter Table Registry Entry Command Message ** -** \param[in] MessagePtr points to the message received via command pipe that needs processing +** \param[in] data points to the message received via command pipe that needs processing ** ** \retval #CFE_TBL_INC_ERR_CTR \copydoc CFE_TBL_INC_ERR_CTR ** \retval #CFE_TBL_INC_CMD_CTR \copydoc CFE_TBL_INC_CMD_CTR @@ -277,9 +277,9 @@ int32 CFE_TBL_SendRegistryCmd(const CFE_TBL_SendRegistry_t *data); ** Deletes a Critical Data Store used to hold a Critical Table's image ** ** \par Assumptions, External Events, and Notes: -** The message pointed to by MessagePtr has been identified as a Delete CDS Command Message +** The message pointed to by data has been identified as a Delete CDS Command Message ** -** \param[in] MessagePtr points to the message received via command pipe that needs processing +** \param[in] data points to the message received via command pipe that needs processing ** ** \retval #CFE_TBL_INC_ERR_CTR \copydoc CFE_TBL_INC_ERR_CTR ** \retval #CFE_TBL_INC_CMD_CTR \copydoc CFE_TBL_INC_CMD_CTR @@ -294,9 +294,9 @@ int32 CFE_TBL_DeleteCDSCmd(const CFE_TBL_DeleteCDS_t *data); ** Frees any resources associated with a previously loaded table. ** ** \par Assumptions, External Events, and Notes: -** The message pointed to by MessagePtr has been identified as an Abort Load Command Message +** The message pointed to by data has been identified as an Abort Load Command Message ** -** \param[in] MessagePtr points to the message received via command pipe that needs processing +** \param[in] data points to the message received via command pipe that needs processing ** ** \retval #CFE_TBL_INC_ERR_CTR \copydoc CFE_TBL_INC_ERR_CTR ** \retval #CFE_TBL_INC_CMD_CTR \copydoc CFE_TBL_INC_CMD_CTR @@ -345,7 +345,6 @@ extern CFE_TBL_CmdProcRet_t CFE_TBL_DumpToFile( const char *DumpFilename, const ** ** \param[in] RegRecPtr Pointer to registry record entry for the table whose load is to be aborted ** -** \return None ******************************************************************************/ void CFE_TBL_AbortLoad(CFE_TBL_RegistryRec_t *RegRecPtr); From 7b56b857afa7af59e8e1baa62d055d4b0ee89664 Mon Sep 17 00:00:00 2001 From: Jacob Hageman Date: Mon, 11 May 2020 08:51:33 -0400 Subject: [PATCH 18/21] HOTFIX: Remove dprecated CFE_FS_IsGzFile test --- fsw/cfe-core/unit-test/fs_UT.c | 53 ---------------------------------- 1 file changed, 53 deletions(-) diff --git a/fsw/cfe-core/unit-test/fs_UT.c b/fsw/cfe-core/unit-test/fs_UT.c index e95acd82f..16411ea32 100644 --- a/fsw/cfe-core/unit-test/fs_UT.c +++ b/fsw/cfe-core/unit-test/fs_UT.c @@ -63,7 +63,6 @@ void UtTest_Setup(void) UT_ADD_TEST(Test_CFE_FS_SetTimestamp); UT_ADD_TEST(Test_CFE_FS_ByteSwapCFEHeader); UT_ADD_TEST(Test_CFE_FS_ByteSwapUint32); - UT_ADD_TEST(Test_CFE_FS_IsGzFile); UT_ADD_TEST(Test_CFE_FS_ExtractFileNameFromPath); UT_ADD_TEST(Test_CFE_FS_Private); } @@ -242,58 +241,6 @@ void Test_CFE_FS_ByteSwapUint32(void) "Byte swap - successful"); } -/* -** Test FS API is .gz file function -*/ -void Test_CFE_FS_IsGzFile(void) -{ -#ifdef UT_VERBOSE - UT_Text("Begin Test Is .gz File\n"); -#endif - - /* Test if file name ends in .gz with the file name too short */ - UT_InitData(); - UT_Report(__FILE__, __LINE__, - CFE_FS_IsGzFile("a") == false, - "CFE_FS_IsGzFile", - "File name too short"); - - /* Test if file name ',gz' extension is missing */ - UT_InitData(); - UT_Report(__FILE__, __LINE__, - CFE_FS_IsGzFile("Normal_gz") == false, - "CFE_FS_IsGzFile", - "File name missing .gz extension 1"); - - /* Test if file name ends in .gz with no file name */ - UT_InitData(); - UT_Report(__FILE__, __LINE__, - CFE_FS_IsGzFile(NULL) == false, - "CFE_FS_IsGzFile", - "Null file name"); - - /* Test a valid file name ending in .gz */ - UT_InitData(); - UT_Report(__FILE__, __LINE__, - CFE_FS_IsGzFile("tar.gz") == true, - "CFE_FS_IsGzFile", - ".gz file name check - successful"); - - /* Test if file name ',gz' extension is missing */ - UT_InitData(); - UT_Report(__FILE__, __LINE__, - CFE_FS_IsGzFile("Normal._z") == false, - "CFE_FS_IsGzFile", - "File name missing .gz extension 2"); - - /* Test if file name ',gz' extension is missing */ - UT_InitData(); - UT_Report(__FILE__, __LINE__, - CFE_FS_IsGzFile("Normal.g_") == false, - "CFE_FS_IsGzFile", - "File name missing .gz extension 3"); -} - /* ** Test FS API write extract file name from path function */ From 6f06b1619648d1bd137be158aba8e25f8d396fae Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Mon, 11 May 2020 12:34:04 -0400 Subject: [PATCH 19/21] HOTFIX: Update to #674, use metadata for packet length. For CFE_SB_SendMsg this was still reading the length directly from the header. It needs to use the metadata value instead. --- fsw/cfe-core/ut-stubs/ut_sb_stubs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fsw/cfe-core/ut-stubs/ut_sb_stubs.c b/fsw/cfe-core/ut-stubs/ut_sb_stubs.c index fe04a804e..c77d4324a 100644 --- a/fsw/cfe-core/ut-stubs/ut_sb_stubs.c +++ b/fsw/cfe-core/ut-stubs/ut_sb_stubs.c @@ -431,7 +431,8 @@ int32 CFE_SB_SendMsg(CFE_SB_Msg_t *MsgPtr) if (status >= 0) { - UT_Stub_CopyFromLocal(UT_KEY(CFE_SB_SendMsg), MsgPtr->Byte, CCSDS_RD_LEN(MsgPtr->Hdr)); + UT_Stub_CopyFromLocal(UT_KEY(CFE_SB_SendMsg), MsgPtr->Byte, + CFE_SB_StubMsg_GetMetaData(MsgPtr)->Length); } return status; From 5b668863a23968420322e76370d00123e15c57de Mon Sep 17 00:00:00 2001 From: Jacob Hageman Date: Mon, 11 May 2020 12:39:01 -0400 Subject: [PATCH 20/21] Fix #491, Add UT macros --- fsw/cfe-core/unit-test/ut_support.c | 142 +++++++++++++++ fsw/cfe-core/unit-test/ut_support.h | 257 ++++++++++++++++++++++++++++ 2 files changed, 399 insertions(+) diff --git a/fsw/cfe-core/unit-test/ut_support.c b/fsw/cfe-core/unit-test/ut_support.c index f72c07445..bbca578d3 100644 --- a/fsw/cfe-core/unit-test/ut_support.c +++ b/fsw/cfe-core/unit-test/ut_support.c @@ -693,3 +693,145 @@ uint32 UT_PrintfIsInHistory(const char *MsgToSearchFor) return UT_GetMessageCount(MsgToSearchFor, &UT_PrintfBuffer, UT_StrCmpFormatStr); } +int32 TestStat; + +void UT_STARTBLOCK_impl(const char *FileName, int LineNum, const char *TestName) +{ +#ifdef VERBOSE + char cMsg[UT_MAX_MESSAGE_LENGTH]; + snprintf(cMsg, UT_MAX_MESSAGE_LENGTH, "%s (%s:%d) Start Block", TestName, FileName, LineNum); + UT_Text(cMsg); +#endif /* VERBOSE */ +} + +void UT_START_impl(const char *FileName, int LineNum, const char *TestName) +{ +#ifdef VERBOSE + char cMsg[UT_MAX_MESSAGE_LENGTH]; + snprintf(cMsg, UT_MAX_MESSAGE_LENGTH, "%s (%s:%d) Start", TestName, FileName, LineNum); + UT_Text(cMsg); +#endif /* VERBOSE */ + + TestStat = CFE_PASS; +} + +void UT_REPORT_impl(const char *FileName, int LineNum, const char *TestName) +{ + UT_Report(FileName, LineNum, TestStat, TestName, "Report"); +} + +bool UT_SETUP_impl(const char *FileName, int LineNum, const char *TestName, const char *FnName, int32 FnRet) +{ + char cMsg[UT_MAX_MESSAGE_LENGTH]; + + if(FnRet != CFE_SUCCESS) + { + snprintf(cMsg, UT_MAX_MESSAGE_LENGTH, "%s (%s:%d) Setup failed (%s returned %ld)", + TestName, FileName, LineNum, FnName, (long int)FnRet); + UT_Text(cMsg); + TestStat = CFE_FAIL; + return false; + } + return true; +} + +bool UT_ASSERT_impl(const char *FileName, int LineNum, const char *TestName, const char *FnName, int32 FnRet) +{ + char cMsg[UT_MAX_MESSAGE_LENGTH]; + + if(FnRet != CFE_SUCCESS) + { + snprintf(cMsg, UT_MAX_MESSAGE_LENGTH, "%s (%s:%d) Assert failed (%s returned %ld)", + TestName, FileName, LineNum, FnName, (long int)FnRet); + UT_Text(cMsg); + TestStat = CFE_FAIL; + return false; + } + return true; +} + +bool UT_ASSERT_EQ_impl(const char *FileName, int LineNum, const char *TestName, + const char *FnName, int32 FnRet, const char *ExpName, int32 Exp) +{ + char cMsg[UT_MAX_MESSAGE_LENGTH]; + + if(FnRet != Exp) + { + snprintf(cMsg, UT_MAX_MESSAGE_LENGTH, "%s (%s:%d) Assert failed (%s [%ld] != %s[%ld])", + TestName, FileName, LineNum, FnName, (long int)FnRet, ExpName, (long int)Exp); + UT_Text(cMsg); + TestStat = CFE_FAIL; + return false; + } + return true; +} + +bool UT_ASSERT_TRUE_impl(const char *FileName, int LineNum, const char *TestName, + const char *ExpName, bool Exp) +{ + char cMsg[UT_MAX_MESSAGE_LENGTH]; + + if(!Exp) + { + snprintf(cMsg, UT_MAX_MESSAGE_LENGTH, "%s (%s:%d) Assert failed (%s)", + TestName, FileName, LineNum, ExpName); + UT_Text(cMsg); + TestStat = CFE_FAIL; + return false; + } + return true; +} + +bool UT_EVTCNT_impl(const char *FileName, int LineNum, const char *TestName, int32 CntExp) +{ + char cMsg[UT_MAX_MESSAGE_LENGTH]; + + int32 CntSent = UT_GetNumEventsSent(); + if(CntSent != CntExp) + { + snprintf(cMsg, UT_MAX_MESSAGE_LENGTH, "%s (%s:%d) Event count (sent: %ld != expected: %ld)", + TestName, FileName, LineNum, (long int)CntSent, (long int)CntExp); + UT_Text(cMsg); + TestStat = CFE_FAIL; + return false; + } + return true; +} + +bool UT_EVTSENT_impl(const char *FileName, int LineNum, const char *TestName, const char *EvtName, int32 EvtId) +{ + char cMsg[UT_MAX_MESSAGE_LENGTH]; + + if(!UT_EventIsInHistory(EvtId)) + { + snprintf(cMsg, UT_MAX_MESSAGE_LENGTH, "%s (%s:%d) Event not sent (%s [%ld])", + TestName, FileName, LineNum, EvtName, (long int)EvtId); + UT_Text(cMsg); + TestStat = CFE_FAIL; + return false; + } + return true; +} + +bool UT_TEARDOWN_impl(const char *FileName, int LineNum, const char *TestName, const char *FnName, int32 FnRet) +{ + char cMsg[UT_MAX_MESSAGE_LENGTH]; + + if(FnRet != CFE_SUCCESS) + { + snprintf(cMsg, UT_MAX_MESSAGE_LENGTH, "%s (%s:%d) Teardown failed (%s returned %ld)", + TestName, FileName, LineNum, FnName, (long int)FnRet); + UT_Text(cMsg); + TestStat = CFE_FAIL; + return false; + } + return true; +} + +void UT_ENDBLOCK_impl(const char *FileName, int LineNum, const char *TestName) +{ +#ifdef VERBOSE + snprintf(cMsg, UT_MAX_MESSAGE_LENGTH, "%s (%s:%d) End Block", TestName, FileName, LineNum); + UT_Text(); +#endif /* VERBOSE */ +} diff --git a/fsw/cfe-core/unit-test/ut_support.h b/fsw/cfe-core/unit-test/ut_support.h index 1c8d8b1bd..25afc12df 100644 --- a/fsw/cfe-core/unit-test/ut_support.h +++ b/fsw/cfe-core/unit-test/ut_support.h @@ -687,4 +687,261 @@ void UT_CheckForOpenSockets(void); ******************************************************************************/ CFE_ES_ResetData_t *UT_GetResetDataPtr(void); +/*****************************************************************************/ +/** +** \brief Global representing the current state of a unit test function. +** +** \par Description +** This global variable is used by the test macros to track whether +** the current test is succeeding or has failed. Many of the macros +** fall through if this is not set to CFE_PASS (usually TestStat +** is set to CFE_PASS by the START() macro and is changed to +** CFE_FAIL by any test step [setup/assert/teardown] that fails). +** +** \par Assumptions, External Events, and Notes: +** None +** +** \sa #CFE_PASS, #CFE_FAIL, #START, #REPORT, #SETUP, #ASSERT, #ASSERT_EQ, #ASSERT_TRUE +** \sa #EVTCNT, #EVTSENT, #TEARDOWN +** +******************************************************************************/ +extern int32 TestStat; + +/*****************************************************************************/ +/** +** \brief Test is currently passing. +** +** \sa #TestStat, #CFE_FAIL +** +******************************************************************************/ +#define CFE_PASS 1 + +/*****************************************************************************/ +/** +** \brief Test has failed. +** +** \sa #TestStat, #CFE_PASS +** +******************************************************************************/ +#define CFE_FAIL 0 + +/** \brief Function to be called by the STARTBLOCK() macro */ +void UT_STARTBLOCK_impl(const char *FileName, int LineNum, const char *TestName); + +/*****************************************************************************/ +/** +** \brief Start a block of tests. +** +** \par Description +** Macro to be called at the start of a test block (a test function +** comprised of calls to multiple individual test functions.) +** +** Does nothing, generates a text entry if VERBOSE is defined. +** +** \par Assumptions, External Events, and Notes: +** None +** +** \sa #ENDBLOCK +** +******************************************************************************/ +#define STARTBLOCK() UT_STARTBLOCK_impl(__FILE__, __LINE__, __func__) + +/** \brief Function to be called by the START() macro */ +void UT_START_impl(const char *FileName, int LineNum, const char *TestName); + +/*****************************************************************************/ +/** +** \brief Start an individual test. +** +** \par Description +** Macro to be called at the start of an individual test. This sets the +** TestStat variable to be CFE_PASS, and generates a text message if +** VERBOSE is defined. +** +** \par Assumptions, External Events, and Notes: +** None +** +** \sa #SETUP, #ASSERT, #ASSERT_EQ, #ASSERT_TRUE, #EVTCNT, #EVTSENT, #REPORT, #TEARDOWN +** +******************************************************************************/ +#define START() UT_START_impl(__FILE__, __LINE__, __func__) + +/** \brief Function to be called by the REPORT() macro */ +void UT_REPORT_impl(const char *FileName, int LineNum, const char *TestName); + +/*****************************************************************************/ +/** +** \brief Report the result of a test. +** +** \par Description +** This reports whether the test passed or failed (as maintained by the +** TestStat global variable.) Call this at the end of every test. +** +** \par Assumptions, External Events, and Notes: +** None +** +** \sa #START, #SETUP, #ASSERT, #ASSERT_EQ, #ASSERT_TRUE, #EVTCNT, #EVTSENT, #TEARDOWN +** +******************************************************************************/ +#define REPORT() UT_REPORT_impl(__FILE__, __LINE__, __func__) + +/** \brief Function to be called by the SETUP() macro */ +bool UT_SETUP_impl(const char *FileName, int LineNum, const char *TestName, const char *FnName, int32 FnRet); + +/*****************************************************************************/ +/** +** \brief Checks the successful execution of a setup function. +** +** \par Description +** Many tests require a number of steps of setup to configure CFE such +** that the actual test can be performed. Failure of any setup steps +** result in a text message and the test being considered failed. +** +** \par Assumptions, External Events, and Notes: +** None +** +** \sa #START, #ASSERT, #ASSERT_EQ, #ASSERT_TRUE, #EVTCNT, #EVTSENT, #REPORT, #TEARDOWN +** +******************************************************************************/ +#define SETUP(FN) (TestStat == CFE_PASS ? UT_SETUP_impl(__FILE__, __LINE__, __func__, (#FN), (FN)) : false) + +/** \brief Function to be called by the ASSERT() macro */ +bool UT_ASSERT_impl(const char *FileName, int LineNum, const char *TestName, const char *FnName, int32 FnRet); + +/*****************************************************************************/ +/** +** \brief Asserts the nominal execution of the function being tested. +** +** \par Description +** The core of each unit test is the execution of the function being tested. +** This function and macro should be used to test the nominal execution of the +** function; the expectation is that it will return CFE_SUCCESS. +** +** \par Assumptions, External Events, and Notes: +** None +** +** \sa #START, #SETUP, #ASSERT_EQ, #ASSERT_TRUE, #EVTCNT, #EVTSENT, #REPORT, #TEARDOWN +** +******************************************************************************/ +#define ASSERT(FN) (TestStat == CFE_PASS ? UT_ASSERT_impl(__FILE__, __LINE__, __func__, (#FN), (FN)) : false) + +/** \brief Function to be called by the ASSERT_EQ() macro */ +bool UT_ASSERT_EQ_impl(const char *FileName, int LineNum, const char *TestName, + const char *FnName, int32 FnRet, const char *ExpName, int32 Exp); + +/*****************************************************************************/ +/** +** \brief Asserts the expected execution of the function being tested. +** +** \par Description +** The core of each unit test is the execution of the function being tested. +** This function and macro should be used to test the execution of the function +** and comparing the return status against the expected return status specified, +** when the return status expected is not CFE_SUCCESS. +** +** \par Assumptions, External Events, and Notes: +** None +** +** \sa #START, #SETUP, #ASSERT, #ASSERT_TRUE, #EVTCNT, #EVTSENT, #REPORT, #TEARDOWN +** +******************************************************************************/ +#define ASSERT_EQ(FN,EXP) (TestStat == CFE_PASS ? UT_ASSERT_EQ_impl(__FILE__, __LINE__, __func__, (#FN), (FN), (#EXP), (EXP)) : false) + +/** \brief Function to be called by the ASSERT_EQ() macro */ +bool UT_ASSERT_TRUE_impl(const char *FileName, int LineNum, const char *TestName, + const char *ExpName, bool Exp); + +/*****************************************************************************/ +/** +** \brief Asserts the expected execution of the function being tested. +** +** \par Description +** The core of each unit test is the execution of the function being tested. +** This function and macro should be used to test the execution of the function +** and comparing the return status against the expected return status specified, +** when the return status expected is not CFE_SUCCESS. +** +** \par Assumptions, External Events, and Notes: +** None +** +** \sa #START, #SETUP, #ASSERT, #ASSERT_TRUE, #EVTCNT, #EVTSENT, #REPORT, #TEARDOWN +** +******************************************************************************/ +#define ASSERT_TRUE(EXP) (TestStat == CFE_PASS ? UT_ASSERT_TRUE_impl(__FILE__, __LINE__, __func__, (#EXP), (EXP)) : false) + +/** \brief Function to be called by the EVTCNT() macro */ +bool UT_EVTCNT_impl(const char *FileName, int LineNum, const char *TestName, int32 CntExp); + +/*****************************************************************************/ +/** +** \brief Ensures that the test generated the expected number of events. +** +** \par Description +** Most tests will generate a number of events, and the number generated +** should be checked via this macro. If the number of events is different, +** the test is considered to have failed and an error is reported. +** +** \par Assumptions, External Events, and Notes: +** None +** +** \sa #START, #SETUP, #ASSERT, #ASSERT_EQ, #ASSERT_TRUE, #EVTSENT, #REPORT, #TEARDOWN +** +******************************************************************************/ +#define EVTCNT(EXP) (TestStat == CFE_PASS ? UT_EVTCNT_impl(__FILE__, __LINE__, __func__, (EXP)) : false) + +/** \brief Function to be called by the EVTSENT() macro */ +bool UT_EVTSENT_impl(const char *FileName, int LineNum, const char *TestName, const char *EvtName, int32 EvtId); + +/*****************************************************************************/ +/** +** \brief Ensures that the test generated the expected event. +** +** \par Description +** Most tests will generate a number of events, and this function and macro check whether an +** event was generated. If not, the test is considered to have failed and an error is reported. +** +** \par Assumptions, External Events, and Notes: +** None +** +** \sa #START, #SETUP, #ASSERT, #ASSERT_EQ, #ASSERT_TRUE, #EVTCNT, #REPORT, #TEARDOWN +** +******************************************************************************/ +#define EVTSENT(EVT) (TestStat == CFE_PASS ? UT_EVTSENT_impl(__FILE__, __LINE__, __func__, (#EVT), (EVT)) : false) + +/** \brief Function to be called by the TEARDOWN() macro */ +bool UT_TEARDOWN_impl(const char *FileName, int LineNum, const char *TestName, const char *FnName, int32 FnRet); +/*****************************************************************************/ +/** +** \brief Checks the successful execution of a teardown function. +** +** \par Description +** Many tests require a number of steps of setup to configure CFE such that the actual test +** can be performed, and undoing that configuration is the role of the teardown steps. Failure +** of any teardown steps result in a text message and the test being considered failed. +** +** \par Assumptions, External Events, and Notes: +** None +** +** \sa #START, #SETUP, #ASSERT, #ASSERT_EQ, #ASSERT_TRUE, #EVTCNT, #EVTSENT, #REPORT +** +******************************************************************************/ +#define TEARDOWN(FN) (TestStat == CFE_PASS ? UT_TEARDOWN_impl(__FILE__, __LINE__, __func__, (#FN), (FN)) : false) + +/*****************************************************************************/ +/** +** \brief Marks the end of a block of tests. +** +** \par Description +** Implementation function and associated ENDBLOCK() macro. Most CFE API functions will be tested with +** a block of tests, each of which will be performed in sequence. This function does +** +** \par Assumptions, External Events, and Notes: +** None +** +** \sa #STARTBLOCK +** +******************************************************************************/ +void UT_ENDBLOCK_impl(const char *FileName, int LineNum, const char *TestName); +#define ENDBLOCK() UT_ENDBLOCK_impl(__FILE__, __LINE__, __func__) + #endif /* __UT_STUBS_H_ */ From f89193f3d25918ef75894cfaacf8d9ac0940e5c3 Mon Sep 17 00:00:00 2001 From: "Gerardo E. Cruz-Ortiz" <59618057+astrogeco@users.noreply.github.com> Date: Wed, 13 May 2020 10:40:12 -0400 Subject: [PATCH 21/21] Increase version to 6.7.17, update Readme and tidy-up markdown. --- README.md | 98 ++++++++++++++++++------------ fsw/cfe-core/src/inc/cfe_version.h | 2 +- 2 files changed, 60 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 84f86273c..97facc4e6 100644 --- a/README.md +++ b/README.md @@ -4,110 +4,130 @@ Travis-CI: [![Build Status](https://travis-ci.com/nasa/cFE.svg)](https://travis- This repository contains NASA's Core Flight Executive (cFE), which is a framework component of the Core Flight System. -This is a collection of services and associated framework to be located in the `cfe` subdirectory of a cFS Mission Tree. The Core Flight System is bundled at https://github.com/nasa/cFS, which includes build and execution instructions. +This is a collection of services and associated framework to be located in the `cfe` subdirectory of a cFS Mission Tree. The Core Flight System is bundled at , which includes build and execution instructions. ## Version History -#### Development Build: 6.7.16 +### Development Build: 6.7.17 + +- No longer automatically decompresses apps/libraries as part of load +- Deletes now unused CFE_ES_CountObjectCallback and CFE_ES_ListResourcesDebug. Flags were unused +- Removes all conditional preprocessing blocks related to CFE_ARINC653. +- Ensure clean build, no warnings on string operations using GCC 9.3.0. +- When OMIT_DEPRECATED = true attempt to send output to shell command will result in command error counter increment (unrecognized function code) +- SBN will need to init command with new MID +- Documentation links and references will now work properly +- API CFE_ES_ProcessCoreException is removed, replaced with async event. +- Removed duplicate prototype in cfe_time_utils.h +- Removes unused defines and adds documentation to TBL event defines. +- Deprecates CFE_TIME_CFE2FSSeconds and CFE_TIME_FS2CFESeconds. +- Unit tests now build and run when MESSAGE_FORMAT_IS_CCSDS_VER_2 is configured. +- Build now works with both extended headers and OMIT_DEPRECATED options set. +- No more alignment warnings +- Adds new unit test macros +- See for more details + +### Development Build: 6.7.16 - Users must now select OSAL options via the CMake file in their defs directory, rather than the osconfig.h file. -- See https://github.com/nasa/cFE/pull/672 for more details +- See for more details -#### Development Build: 6.7.15 +### Development Build: 6.7.15 - Upon power on reset, default system log mode set to overwrite. Upon processor reset, default system log mode set to discard. - No longer locks while locked (no issue observed on linux/posix, but user reported issue on FreeRTOS 10) - Internal `CFE_TBL_LoadFromFile()` API changed slightly to add AppName as a parameter. Return value from `LoadFromFile()` no longer relevant for event generation. - Updates `CFE_TBL_CleanUpApp` such that it now checks the 'used flag' prior to calling `CFE_TBL_RemoveAccessLink` for a given TblHandle. Also sets the AppId to `CFE_TBL_NOT_OWNED` after removing the access descriptor link from linked list. - Removed `OS_FS_SUCCESS, OS_FS_ERROR , OS_FS_ERR_INVALID_POINTER, OS_FS_ERR_NO_FREE_FDS , OS_FS_ERR_INVALID_FD, and OS_FS_UNIMPLEMENTED` from `osapi-os-filesys.h` -- See https://github.com/nasa/cFE/pull/649 for more details +- See for more details -#### Development Build: 6.7.14 +### Development Build: 6.7.14 - Exposes the `CFE_SB_IsValidMsgId()` for application usage. - `CFE_SB_GetLastSenderID` will now detect if it is being called prior to a message being sent on a given pipe. - Mismatches between PSP/BSP/OS are now detected and warned about during make prep. Only the `CFE_SYSTEM_PSPNAME` is actually required to be specified for a CFE build now. Others can be omitted. -- See https://github.com/nasa/cFE/pull/635 for more details +- See for more details -#### Development Build: 6.7.13 +### Development Build: 6.7.13 - RTEMS builds without error. - Use the INTERFACE_COMPILE_DEFINITIONS and INTERFACE_INCLUDE_DIRECTORIES properties from the osal target and apply them to the entire CFE build as a directory-scope property. No impact until these are set in OSAL. -- Minor other updates (see https://github.com/nasa/cFE/pull/615) +- Minor other updates (see ) -#### Development Build: 6.7.12 +### Development Build: 6.7.12 - Cmd code (and checksum) are always in the same place (matches GSFC spec for command secondary header) - No impact to behavior. Previously the perf log dump file frequently contained errors due to out of order or otherwise corrupted entries, which is now fixed. -- Minor other updates (see https://github.com/nasa/cFE/pull/586) +- Minor other updates (see ) -#### Development Build: 6.7.11 +### Development Build: 6.7.11 - Improve documentation - Update makefile to report branch coverage -- Minor other updates (see https://github.com/nasa/cFE/pull/566) +- Minor other updates (see ) -#### Development Build: 6.7.10 +### Development Build: 6.7.10 - Fix potential unit test problems with name collisions - Improve documentation -- Minor other updates (see https://github.com/nasa/cFE/pull/563) +- Minor other updates (see ) -#### Development Build: 6.7.9 +### Development Build: 6.7.9 -- No longer requires sed "hack" to change the setting in default_config.h -- Minor other updates (see https://github.com/nasa/cFE/pull/544) +- No longer requires sed "hack" to change the setting in default_config.h +- Minor other updates (see ) + +### Development Build: 6.7.8 -#### Development Build: 6.7.8 - Updates and cleaned up documentation and requirements - Fixes incorrect debug messages - Decrease child task count when one is deleted -- Minor other updates (see https://github.com/nasa/cFE/pull/530) +- Minor other updates (see ) -#### Development Build: 6.7.7 +### Development Build: 6.7.7 - Adds a new function, CFE_SB_GetPipeIdByName, which retrieves the pipe ID given a name of a pipe. - Improvement in error reporting when using a pipe name that is already in use, or when the queue limit has been reached. - Added userguide and osalguide to the local target list to avoid makefile warning -- Minor other updates (see https://github.com/nasa/cFE/pull/511) +- Minor other updates (see ) -#### Development Build: 6.7.6 +### Development Build: 6.7.6 - Adds OMIT_DEPRECATED prep flag - Adds and enforces strict warnings - Software Bus now increments sequence counter even if there are no subscribers -- Warning, comment, and code coverage cleanup (see https://github.com/nasa/cFE/pull/490) +- Warning, comment, and code coverage cleanup (see ) -#### Development Build: 6.7.5 +### Development Build: 6.7.5 - Added CI static analysis check - Resolved static analysis warnings -- Minor other updates (see https://github.com/nasa/cFE/pull/479) +- Minor other updates (see ) -#### Development Build: 6.7.4 +### Development Build: 6.7.4 -- Minor updates (see https://github.com/nasa/cFE/pull/448) +- Minor updates (see ) -#### Development Build: 6.7.3 +### Development Build: 6.7.3 -- Minor updates (see https://github.com/nasa/cFE/pull/413) +- Minor updates (see ) -#### Development Build: 6.7.2 +### Development Build: 6.7.2 -- Minor bugs and enhancements (see https://github.com/nasa/cFE/pull/388) +- Minor bugs and enhancements (see ) -#### Development Build: 6.7.1 +### Development Build: 6.7.1 -- Fix strlen in CFE_ES_TaskInit https://github.com/nasa/cFE/pull/23 -- Minor bug fixes (see https://github.com/nasa/cFE/pull/378) +- Fix strlen in CFE_ES_TaskInit +- Minor bug fixes (see ) -### ***OFFICIAL RELEASE: 6.7.0*** +### **_OFFICIAL RELEASE: 6.7.0_** - This is a point release from an internal repository - Changes are detailed in [cFS repo](https://github.com/nasa/cFS) release documentation - Apache 2.0 -### ***OFFICIAL RELEASE: 6.6.0a*** +### **_OFFICIAL RELEASE: 6.6.0a_** - This is a point release from an internal repository - Apache 2.0 @@ -121,6 +141,6 @@ See all open issues and closed to milestones later than this version. ## Getting Help -For best results, submit issues:questions or issues:help wanted requests at https://github.com/nasa/cFS. +For best results, submit issues:questions or issues:help wanted requests at . -Official cFS page: http://cfs.gsfc.nasa.gov +Official cFS page: diff --git a/fsw/cfe-core/src/inc/cfe_version.h b/fsw/cfe-core/src/inc/cfe_version.h index cece97638..17429ffa1 100644 --- a/fsw/cfe-core/src/inc/cfe_version.h +++ b/fsw/cfe-core/src/inc/cfe_version.h @@ -95,7 +95,7 @@ */ #define CFE_MAJOR_VERSION 6 #define CFE_MINOR_VERSION 7 -#define CFE_REVISION 16 +#define CFE_REVISION 17 #endif /* _cfe_version_ */