diff options
Diffstat (limited to 'FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/DemoTasks/DefenderDemoExample.c')
-rw-r--r-- | FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/DemoTasks/DefenderDemoExample.c | 136 |
1 files changed, 67 insertions, 69 deletions
diff --git a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/DemoTasks/DefenderDemoExample.c b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/DemoTasks/DefenderDemoExample.c index 0a2031aae..12b0100cc 100644 --- a/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/DemoTasks/DefenderDemoExample.c +++ b/FreeRTOS-Plus/Demo/AWS/Device_Defender_Windows_Simulator/Device_Defender_Demo/DemoTasks/DefenderDemoExample.c @@ -198,16 +198,6 @@ static uint16_t pusOpenUdpPorts[ democonfigOPEN_UDP_PORTS_ARRAY_SIZE ]; static Connection_t pxEstablishedConnections[ democonfigESTABLISHED_CONNECTIONS_ARRAY_SIZE ]; /** - * @brief Array of task statuses, used to generate custom metrics. - */ -static TaskStatus_t pxTaskStatusList[ democonfigCUSTOM_METRICS_TASKS_ARRAY_SIZE ]; - -/** - * @brief Task numbers custom metric array. - */ -static uint32_t pulCustomMetricsTaskNumbers[ democonfigCUSTOM_METRICS_TASKS_ARRAY_SIZE ]; - -/** * @brief All the metrics sent in the Device Defender report. */ static ReportMetrics_t xDeviceMetrics; @@ -243,6 +233,8 @@ static void prvPublishCallback( MQTTContext_t * pxMqttContext, /** * @brief Collect all the metrics to be sent in the Device Defender report. * + * On success, caller is responsible for freeing xDeviceMetrics.pxTaskStatusArray. + * * @return true if all the metrics are successfully collected; * false otherwise. */ @@ -251,12 +243,12 @@ static bool prvCollectDeviceMetrics( void ); /** * @brief Generate the Device Defender report. * - * @param[out] pulOutReportLength Length of the Device Defender report. + * @param[out] pxOutReportLength Length of the Device Defender report. * * @return true if the report is generated successfully; * false otherwise. */ -static bool prvGenerateDeviceMetricsReport( uint32_t * pulOutReportLength ); +static bool prvGenerateDeviceMetricsReport( size_t * pxOutReportLength ); /** * @brief Subscribe to the Device Defender topics. @@ -277,12 +269,12 @@ static bool prvUnsubscribeFromDefenderTopics( void ); /** * @brief Publish the generated Device Defender report. * - * @param[in] ulReportLength Length of the Device Defender report. + * @param[in] xReportLength Length of the Device Defender report. * * @return true if the report is published successfully; * false otherwise. */ -static bool prvPublishDeviceMetricsReport( uint32_t ulReportLength ); +static bool prvPublishDeviceMetricsReport( size_t xReportLength ); /** * @brief Validate the response received from the AWS IoT Device Defender Service. @@ -291,13 +283,13 @@ static bool prvPublishDeviceMetricsReport( uint32_t ulReportLength ); * is same as was sent in the published report. * * @param[in] pcDefenderResponse The defender response to validate. - * @param[in] ulDefenderResponseLength Length of the defender response. + * @param[in] xDefenderResponseLength Length of the defender response. * * @return true if the response is valid; * false otherwise. */ static bool prvValidateDefenderResponse( const char * pcDefenderResponse, - uint32_t ulDefenderResponseLength ); + size_t xDefenderResponseLength ); /** * @brief The task used to demonstrate the Defender API. @@ -316,7 +308,7 @@ static void prvDefenderDemoTask( void * pvParameters ); /*-----------------------------------------------------------*/ static bool prvValidateDefenderResponse( const char * pcDefenderResponse, - uint32_t ulDefenderResponseLength ) + size_t xDefenderResponseLength ) { bool xStatus = false; JSONStatus_t eJsonResult = JSONSuccess; @@ -327,12 +319,12 @@ static bool prvValidateDefenderResponse( const char * pcDefenderResponse, configASSERT( pcDefenderResponse != NULL ); /* Is the response a valid JSON? */ - eJsonResult = JSON_Validate( pcDefenderResponse, ulDefenderResponseLength ); + eJsonResult = JSON_Validate( pcDefenderResponse, xDefenderResponseLength ); if( eJsonResult != JSONSuccess ) { LogError( ( "Invalid response from AWS IoT Device Defender Service: %.*s.", - ( int ) ulDefenderResponseLength, + ( int ) xDefenderResponseLength, pcDefenderResponse ) ); } @@ -340,7 +332,7 @@ static bool prvValidateDefenderResponse( const char * pcDefenderResponse, { /* Search the ReportId key in the response. */ eJsonResult = JSON_Search( ( char * ) pcDefenderResponse, - ulDefenderResponseLength, + xDefenderResponseLength, DEFENDER_RESPONSE_REPORT_ID_FIELD, DEFENDER_RESPONSE_REPORT_ID_FIELD_LENGTH, &( ucReportIdString ), @@ -351,7 +343,7 @@ static bool prvValidateDefenderResponse( const char * pcDefenderResponse, LogError( ( "%s key not found in the response from the" "AWS IoT Device Defender Service: %.*s.", DEFENDER_RESPONSE_REPORT_ID_FIELD, - ( int ) ulDefenderResponseLength, + ( int ) xDefenderResponseLength, pcDefenderResponse ) ); } } @@ -376,7 +368,7 @@ static bool prvValidateDefenderResponse( const char * pcDefenderResponse, DEFENDER_RESPONSE_REPORT_ID_FIELD, ulReportId, ulReportIdInResponse, - ( int ) ulDefenderResponseLength, + ( int ) xDefenderResponseLength, pcDefenderResponse ) ); } } @@ -476,9 +468,11 @@ static bool prvCollectDeviceMetrics( void ) { bool xStatus = false; eMetricsCollectorStatus eStatus; - uint32_t ulNumOpenTcpPorts = 0UL, ulNumOpenUdpPorts = 0UL, ulNumEstablishedConnections = 0UL, i; + size_t xNumOpenTcpPorts = 0UL, xNumOpenUdpPorts = 0UL, xNumEstablishedConnections = 0UL, i; UBaseType_t uxTasksWritten = { 0 }; + UBaseType_t uxNumTasksRunning; TaskStatus_t pxTaskStatus = { 0 }; + TaskStatus_t * pxTaskStatusArray = NULL; /* Collect bytes and packets sent and received. */ eStatus = eGetNetworkStats( &( xNetworkStats ) ); @@ -494,7 +488,7 @@ static bool prvCollectDeviceMetrics( void ) { eStatus = eGetOpenTcpPorts( &( pusOpenTcpPorts[ 0 ] ), democonfigOPEN_TCP_PORTS_ARRAY_SIZE, - &( ulNumOpenTcpPorts ) ); + &( xNumOpenTcpPorts ) ); if( eStatus != eMetricsCollectorSuccess ) { @@ -508,7 +502,7 @@ static bool prvCollectDeviceMetrics( void ) { eStatus = eGetOpenUdpPorts( &( pusOpenUdpPorts[ 0 ] ), democonfigOPEN_UDP_PORTS_ARRAY_SIZE, - &( ulNumOpenUdpPorts ) ); + &( xNumOpenUdpPorts ) ); if( eStatus != eMetricsCollectorSuccess ) { @@ -522,7 +516,7 @@ static bool prvCollectDeviceMetrics( void ) { eStatus = eGetEstablishedConnections( &( pxEstablishedConnections[ 0 ] ), democonfigESTABLISHED_CONNECTIONS_ARRAY_SIZE, - &( ulNumEstablishedConnections ) ); + &( xNumEstablishedConnections ) ); if( eStatus != eMetricsCollectorSuccess ) { @@ -531,33 +525,18 @@ static bool prvCollectDeviceMetrics( void ) } } - /* Collect custom metrics. This demo sends this task's stack high water mark - * as a number type custom metric and the current task IDs as a list of - * numbers type custom metric. */ if( eStatus == eMetricsCollectorSuccess ) { - vTaskGetInfo( - /* Query this task. */ - NULL, - &pxTaskStatus, - /* Include the stack high water mark value. */ - pdTRUE, - /* Don't include the task state in the TaskStatus_t structure. */ - 0 ); - uxTasksWritten = uxTaskGetSystemState( pxTaskStatusList, democonfigCUSTOM_METRICS_TASKS_ARRAY_SIZE, NULL ); + /* Get task count */ + uxNumTasksRunning = uxTaskGetNumberOfTasks(); - if( uxTasksWritten == 0 ) + /* Allocate pxTaskStatusArray */ + pxTaskStatusArray = pvPortMalloc( uxNumTasksRunning * sizeof( TaskStatus_t ) ); + + if( pxTaskStatusArray == NULL ) { + LogError( ( "Cannot allocate memory for pxTaskStatusArray: pvPortMalloc() failed." ) ); eStatus = eMetricsCollectorCollectionFailed; - LogError( ( "Failed to collect system state. uxTaskGetSystemState() failed due to insufficient buffer space.", - eStatus ) ); - } - else - { - for( i = 0; i < uxTasksWritten; i++ ) - { - pulCustomMetricsTaskNumbers[ i ] = pxTaskStatusList[ i ].xTaskNumber; - } } } @@ -566,6 +545,9 @@ static bool prvCollectDeviceMetrics( void ) * numbers type custom metric. */ if( eStatus == eMetricsCollectorSuccess ) { + /* Get the current task's status information. The usStackHighWaterMark + * field of the task status will be included in the report as a "number" + * custom metric. */ vTaskGetInfo( /* Query this task. */ NULL, @@ -574,21 +556,20 @@ static bool prvCollectDeviceMetrics( void ) pdTRUE, /* Don't include the task state in the TaskStatus_t structure. */ 0 ); - uxTasksWritten = uxTaskGetSystemState( pxTaskStatusList, democonfigCUSTOM_METRICS_TASKS_ARRAY_SIZE, NULL ); + /* Get the task status information for all running tasks. The task IDs + * of each task is then extracted to include in the report as a "list of + * numbers" custom metric */ + uxTasksWritten = uxTaskGetSystemState( pxTaskStatusArray, uxNumTasksRunning, NULL ); if( uxTasksWritten == 0 ) { + /* If 0 is returned, the buffer was too small. This line is reached + * when we hit the race condition where tasks have been added since + * we got the result of uxTaskGetNumberOfTasks() */ eStatus = eMetricsCollectorCollectionFailed; LogError( ( "Failed to collect system state. uxTaskGetSystemState() failed due to insufficient buffer space.", eStatus ) ); } - else - { - for( i = 0; i < uxTasksWritten; i++ ) - { - pulCustomMetricsTaskNumbers[ i ] = pxTaskStatusList[ i ].xTaskNumber; - } - } } /* Populate device metrics. */ @@ -597,21 +578,30 @@ static bool prvCollectDeviceMetrics( void ) xStatus = true; xDeviceMetrics.pxNetworkStats = &( xNetworkStats ); xDeviceMetrics.pusOpenTcpPortsArray = &( pusOpenTcpPorts[ 0 ] ); - xDeviceMetrics.ulOpenTcpPortsArrayLength = ulNumOpenTcpPorts; + xDeviceMetrics.xOpenTcpPortsArrayLength = xNumOpenTcpPorts; xDeviceMetrics.pusOpenUdpPortsArray = &( pusOpenUdpPorts[ 0 ] ); - xDeviceMetrics.ulOpenUdpPortsArrayLength = ulNumOpenUdpPorts; + xDeviceMetrics.xOpenUdpPortsArrayLength = xNumOpenUdpPorts; xDeviceMetrics.pxEstablishedConnectionsArray = &( pxEstablishedConnections[ 0 ] ); - xDeviceMetrics.ulEstablishedConnectionsArrayLength = ulNumEstablishedConnections; + xDeviceMetrics.xEstablishedConnectionsArrayLength = xNumEstablishedConnections; xDeviceMetrics.ulStackHighWaterMark = pxTaskStatus.usStackHighWaterMark; - xDeviceMetrics.pulTaskIdArray = pulCustomMetricsTaskNumbers; - xDeviceMetrics.ulTaskIdArrayLength = uxTasksWritten; + xDeviceMetrics.pxTaskStatusArray = pxTaskStatusArray; + xDeviceMetrics.xTaskStatusArrayLength = uxTasksWritten; + } + else + { + /* Free pxTaskStatusArray if we allocated it but did not add it to the + * xDeviceMetrics struct. */ + if( pxTaskStatusArray != NULL ) + { + vPortFree( pxTaskStatusArray ); + } } return xStatus; } /*-----------------------------------------------------------*/ -static bool prvGenerateDeviceMetricsReport( uint32_t * pulOutReportLength ) +static bool prvGenerateDeviceMetricsReport( size_t * pxOutReportLength ) { bool xStatus = false; eReportBuilderStatus eReportBuilderStatus; @@ -624,7 +614,7 @@ static bool prvGenerateDeviceMetricsReport( uint32_t * pulOutReportLength ) democonfigDEVICE_METRICS_REPORT_MAJOR_VERSION, democonfigDEVICE_METRICS_REPORT_MINOR_VERSION, ulReportId, - pulOutReportLength ); + pxOutReportLength ); if( eReportBuilderStatus != eReportBuilderSuccess ) { @@ -634,7 +624,7 @@ static bool prvGenerateDeviceMetricsReport( uint32_t * pulOutReportLength ) else { LogDebug( ( "Generated Report: %.*s.", - *pulOutReportLength, + *pxOutReportLength, &( pcDeviceMetricsJsonReport[ 0 ] ) ) ); xStatus = true; } @@ -699,13 +689,13 @@ static bool prvUnsubscribeFromDefenderTopics( void ) } /*-----------------------------------------------------------*/ -static bool prvPublishDeviceMetricsReport( uint32_t reportLength ) +static bool prvPublishDeviceMetricsReport( size_t xReportLength ) { return xPublishToTopic( &xMqttContext, DEFENDER_API_JSON_PUBLISH( democonfigTHING_NAME ), DEFENDER_API_LENGTH_JSON_PUBLISH( THING_NAME_LENGTH ), &( pcDeviceMetricsJsonReport[ 0 ] ), - reportLength ); + xReportLength ); } /*-----------------------------------------------------------*/ @@ -732,7 +722,8 @@ void prvDefenderDemoTask( void * pvParameters ) { bool xStatus = false; BaseType_t xExitStatus = EXIT_FAILURE; - uint32_t ulReportLength = 0UL, i, ulMqttSessionEstablished = 0UL; + uint32_t ulReportLength = 0UL, i; + bool xMqttSessionEstablished = false; UBaseType_t uxDemoRunCount = 0UL; /* Remove compiler warnings about unused parameters. */ @@ -777,7 +768,7 @@ void prvDefenderDemoTask( void * pvParameters ) } else { - ulMqttSessionEstablished = 1; + xMqttSessionEstablished = true; } /******************** Subscribe to Defender topics. *******************/ @@ -853,6 +844,13 @@ void prvDefenderDemoTask( void * pvParameters ) LogInfo( ( "Generating Device Defender report..." ) ); xStatus = prvGenerateDeviceMetricsReport( &( ulReportLength ) ); + /* Free the allocated array in xDeviceMetrics struct which is not + * used anymore after prvGenerateDeviceMetricsReport(). This code is + * only reached when prvCollectDeviceMetrics succeeded, so + * xDeviceMetrics.pxTaskStatusArray is a valid allocation that needs + * to be freed. */ + vPortFree( xDeviceMetrics.pxTaskStatusArray ); + if( xStatus != true ) { LogError( ( "Failed to generate Device Defender report." ) ); @@ -908,7 +906,7 @@ void prvDefenderDemoTask( void * pvParameters ) * protocol spec, it is okay to send UNSUBSCRIBE even if no corresponding * subscription exists on the broker. Therefore, it is okay to attempt * unsubscribe even if one more subscribe failed earlier. */ - if( ulMqttSessionEstablished == 1 ) + if( xMqttSessionEstablished ) { LogInfo( ( "Unsubscribing from defender topics..." ) ); xStatus = prvUnsubscribeFromDefenderTopics(); |