summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSukhmani Minhas <50919130+sukhmanm@users.noreply.github.com>2020-11-19 20:03:59 -0500
committerGitHub <noreply@github.com>2020-11-19 20:03:59 -0500
commit56a86428fecd42684fc2bfe5781986db9b9058fb (patch)
tree72cfaa2a99e9b291745af4be8777e403a5602055
parente313e286df3e70dfed2a9c434b041bc4dc9710ca (diff)
downloadfreertos-git-56a86428fecd42684fc2bfe5781986db9b9058fb.tar.gz
Preparation for coreHTTP demos (#413)
Adding common utilities that will be used by 4 coreHTTP demos: - Adding coreHTTP submodule pointer to FreeRTOS-Plus/Source/Application-Protocols/coreHTTP - Adding folder FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Http_Demo_Helpers with functions common to demos.
-rw-r--r--.gitmodules3
-rw-r--r--FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/main.c376
-rw-r--r--FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Http_Demo_Helpers/http_demo_utils.c196
-rw-r--r--FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Http_Demo_Helpers/http_demo_utils.h126
-rw-r--r--FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Http_Demo_Helpers/presigned_url_generator/README.md55
-rw-r--r--FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Http_Demo_Helpers/presigned_url_generator/presigned_urls_gen.py68
m---------FreeRTOS-Plus/Source/Application-Protocols/coreHTTP0
7 files changed, 824 insertions, 0 deletions
diff --git a/.gitmodules b/.gitmodules
index b12b4b5cb..9ac800c5a 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -31,3 +31,6 @@
[submodule "FreeRTOS-Plus/Source/AWS/device-defender"]
path = FreeRTOS-Plus/Source/AWS/device-defender
url = https://github.com/aws/device-defender-for-aws-iot-embedded-sdk.git
+[submodule "FreeRTOS-Plus/Source/Application-Protocols/coreHTTP"]
+ path = FreeRTOS-Plus/Source/Application-Protocols/coreHTTP
+ url = https://github.com/FreeRTOS/coreHTTP
diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/main.c b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/main.c
new file mode 100644
index 000000000..17b5c3900
--- /dev/null
+++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Common/main.c
@@ -0,0 +1,376 @@
+/*
+ * FreeRTOS Kernel V10.3.0
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ */
+
+/***
+ * See https://www.FreeRTOS.org for configuration and usage instructions.
+ ***/
+
+/* Standard includes. */
+#include <stdio.h>
+#include <time.h>
+
+/* Visual studio intrinsics used so the __debugbreak() function is available
+ * should an assert get hit. */
+#include <intrin.h>
+
+/* FreeRTOS includes. */
+#include <FreeRTOS.h>
+#include "task.h"
+
+/* TCP/IP stack includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+
+/* Demo logging includes. */
+#include "logging.h"
+
+/* Demo Specific configs. */
+#include "demo_config.h"
+
+
+/*
+ * Prototypes for the demos that can be started from this project. Note that the
+ * HTTP demo is not actually started until the network is ready, which is
+ * indicated by vApplicationIPNetworkEventHook() executing - hence
+ * vStartSimpleHTTPDemo() is called from inside vApplicationIPNetworkEventHook().
+ */
+extern void vStartSimpleHTTPDemo( void );
+
+/*
+ * Just seeds the simple pseudo random number generator.
+ *
+ * !!! NOTE !!!
+ * This is not a secure method of generating random numbers and production
+ * devices should use a true random number generator (TRNG).
+ */
+static void prvSRand( UBaseType_t ulSeed );
+
+/*
+ * Miscellaneous initialization including preparing the logging and seeding the
+ * random number generator.
+ */
+static void prvMiscInitialisation( void );
+
+/* The default IP and MAC address used by the demo. The address configuration
+ * defined here will be used if ipconfigUSE_DHCP is 0, or if ipconfigUSE_DHCP is
+ * 1 but a DHCP server could not be contacted. See the online documentation for
+ * more information. */
+static const uint8_t ucIPAddress[ 4 ] = { configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 };
+static const uint8_t ucNetMask[ 4 ] = { configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 };
+static const uint8_t ucGatewayAddress[ 4 ] = { configGATEWAY_ADDR0, configGATEWAY_ADDR1, configGATEWAY_ADDR2, configGATEWAY_ADDR3 };
+static const uint8_t ucDNSServerAddress[ 4 ] = { configDNS_SERVER_ADDR0, configDNS_SERVER_ADDR1, configDNS_SERVER_ADDR2, configDNS_SERVER_ADDR3 };
+
+/* Set the following constant to pdTRUE to log using the method indicated by the
+ * name of the constant, or pdFALSE to not log using the method indicated by the
+ * name of the constant. Options include to standard out (xLogToStdout), to a disk
+ * file (xLogToFile), and to a UDP port (xLogToUDP). If xLogToUDP is set to pdTRUE
+ * then UDP messages are sent to the IP address configured as the UDP logging server
+ * address (see the configUDP_LOGGING_ADDR0 definitions in FreeRTOSConfig.h) and
+ * the port number set by configPRINT_PORT in FreeRTOSConfig.h. */
+const BaseType_t xLogToStdout = pdTRUE, xLogToFile = pdFALSE, xLogToUDP = pdFALSE;
+
+/* Default MAC address configuration. The demo creates a virtual network
+ * connection that uses this MAC address by accessing the raw Ethernet data
+ * to and from a real network connection on the host PC. See the
+ * configNETWORK_INTERFACE_TO_USE definition for information on how to configure
+ * the real network connection to use. */
+const uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 };
+
+/* Used by the pseudo random number generator. */
+static UBaseType_t ulNextRand;
+/*-----------------------------------------------------------*/
+
+int main( void )
+{
+ /* Miscellaneous initialization including preparing the logging and seeding
+ * the random number generator. */
+ prvMiscInitialisation();
+
+ /* Initialize the network interface.
+ *
+ ***NOTE*** Tasks that use the network are created in the network event hook
+ * when the network is connected and ready for use (see the implementation of
+ * vApplicationIPNetworkEventHook() below). The address values passed in here
+ * are used if ipconfigUSE_DHCP is set to 0, or if ipconfigUSE_DHCP is set to 1
+ * but a DHCP server cannot be contacted. */
+ FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress );
+
+ /* Start the RTOS scheduler. */
+ vTaskStartScheduler();
+
+ /* If all is well, the scheduler will now be running, and the following
+ * line will never be reached. If the following line does execute, then
+ * there was insufficient FreeRTOS heap memory available for the idle and/or
+ * timer tasks to be created. See the memory management section on the
+ * FreeRTOS web site for more details (this is standard text that is not
+ * really applicable to the Win32 simulator port). */
+ for( ; ; )
+ {
+ __debugbreak();
+ }
+}
+/*-----------------------------------------------------------*/
+
+/* Called by FreeRTOS+TCP when the network connects or disconnects. Disconnect
+ * events are only received if implemented in the MAC driver. */
+void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
+{
+ uint32_t ulIPAddress, ulNetMask, ulGatewayAddress, ulDNSServerAddress;
+ char cBuffer[ 16 ];
+ static BaseType_t xTasksAlreadyCreated = pdFALSE;
+
+ /* If the network has just come up...*/
+ if( eNetworkEvent == eNetworkUp )
+ {
+ /* Create the tasks that use the IP stack if they have not already been
+ * created. */
+ if( xTasksAlreadyCreated == pdFALSE )
+ {
+ /* Demos that use the network are created after the network is
+ * up. */
+ LogInfo( ( "---------STARTING DEMO---------\r\n" ) );
+ vStartSimpleHTTPDemo();
+ xTasksAlreadyCreated = pdTRUE;
+ }
+
+ /* Print out the network configuration, which may have come from a DHCP
+ * server. */
+ FreeRTOS_GetAddressConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress );
+ FreeRTOS_inet_ntoa( ulIPAddress, cBuffer );
+ LogInfo( ( "\r\n\r\nIP Address: %s\r\n", cBuffer ) );
+
+ FreeRTOS_inet_ntoa( ulNetMask, cBuffer );
+ LogInfo( ( "Subnet Mask: %s\r\n", cBuffer ) );
+
+ FreeRTOS_inet_ntoa( ulGatewayAddress, cBuffer );
+ LogInfo( ( "Gateway Address: %s\r\n", cBuffer ) );
+
+ FreeRTOS_inet_ntoa( ulDNSServerAddress, cBuffer );
+ LogInfo( ( "DNS Server Address: %s\r\n\r\n\r\n", cBuffer ) );
+ }
+}
+/*-----------------------------------------------------------*/
+
+void vAssertCalled( const char * pcFile,
+ uint32_t ulLine )
+{
+ volatile uint32_t ulBlockVariable = 0UL;
+ volatile char * pcFileName = ( volatile char * ) pcFile;
+ volatile uint32_t ulLineNumber = ulLine;
+
+ ( void ) pcFileName;
+ ( void ) ulLineNumber;
+
+ printf( "vAssertCalled( %s, %u\n", pcFile, ulLine );
+
+ /* Setting ulBlockVariable to a non-zero value in the debugger will allow
+ * this function to be exited. */
+ taskDISABLE_INTERRUPTS();
+ {
+ while( ulBlockVariable == 0UL )
+ {
+ __debugbreak();
+ }
+ }
+ taskENABLE_INTERRUPTS();
+}
+/*-----------------------------------------------------------*/
+
+UBaseType_t uxRand( void )
+{
+ const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL;
+
+ /*
+ * Utility function to generate a pseudo random number.
+ *
+ * !!!NOTE!!!
+ * This is not a secure method of generating a random number. Production
+ * devices should use a True Random Number Generator (TRNG).
+ */
+ ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;
+ return( ( int ) ( ulNextRand >> 16UL ) & 0x7fffUL );
+}
+/*-----------------------------------------------------------*/
+
+static void prvSRand( UBaseType_t ulSeed )
+{
+ /* Utility function to seed the pseudo random number generator. */
+ ulNextRand = ulSeed;
+}
+/*-----------------------------------------------------------*/
+
+static void prvMiscInitialisation( void )
+{
+ time_t xTimeNow;
+ uint32_t ulLoggingIPAddress;
+
+ ulLoggingIPAddress = FreeRTOS_inet_addr_quick( configUDP_LOGGING_ADDR0, configUDP_LOGGING_ADDR1, configUDP_LOGGING_ADDR2, configUDP_LOGGING_ADDR3 );
+ vLoggingInit( xLogToStdout, xLogToFile, xLogToUDP, ulLoggingIPAddress, configPRINT_PORT );
+
+ /*
+ * Seed random number generator.
+ *
+ * !!!NOTE!!!
+ * This is not a secure method of generating a random number. Production
+ * devices should use a True Random Number Generator (TRNG).
+ */
+ time( &xTimeNow );
+ LogDebug( ( "Seed for randomizer: %lu\n", xTimeNow ) );
+ prvSRand( ( uint32_t ) xTimeNow );
+ LogDebug( ( "Random numbers: %08X %08X %08X %08X\n", ipconfigRAND32(), ipconfigRAND32(), ipconfigRAND32(), ipconfigRAND32() ) );
+}
+/*-----------------------------------------------------------*/
+
+#if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) || ( ipconfigDHCP_REGISTER_HOSTNAME == 1 )
+
+ const char * pcApplicationHostnameHook( void )
+ {
+ /* Assign the name "FreeRTOS" to this network node. This function will
+ * be called during the DHCP: the machine will be registered with an IP
+ * address plus this name. */
+ return mainHOST_NAME;
+ }
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 )
+
+ BaseType_t xApplicationDNSQueryHook( const char * pcName )
+ {
+ BaseType_t xReturn;
+
+ /* Determine if a name lookup is for this node. Two names are given
+ * to this node: that returned by pcApplicationHostnameHook() and that set
+ * by mainDEVICE_NICK_NAME. */
+ if( _stricmp( pcName, pcApplicationHostnameHook() ) == 0 )
+ {
+ xReturn = pdPASS;
+ }
+ else if( _stricmp( pcName, mainDEVICE_NICK_NAME ) == 0 )
+ {
+ xReturn = pdPASS;
+ }
+ else
+ {
+ xReturn = pdFAIL;
+ }
+
+ return xReturn;
+ }
+
+#endif /* if ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) */
+/*-----------------------------------------------------------*/
+
+/*
+ * Callback that provides the inputs necessary to generate a randomized TCP
+ * Initial Sequence Number per RFC 6528. THIS IS ONLY A DUMMY IMPLEMENTATION
+ * THAT RETURNS A PSEUDO RANDOM NUMBER SO IS NOT INTENDED FOR USE IN PRODUCTION
+ * SYSTEMS.
+ */
+extern uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress,
+ uint16_t usSourcePort,
+ uint32_t ulDestinationAddress,
+ uint16_t usDestinationPort )
+{
+ ( void ) ulSourceAddress;
+ ( void ) usSourcePort;
+ ( void ) ulDestinationAddress;
+ ( void ) usDestinationPort;
+
+ return uxRand();
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Set *pulNumber to a random number, and return pdTRUE. When the random number
+ * generator is broken, it shall return pdFALSE.
+ * The macros ipconfigRAND32() and configRAND32() are not in use
+ * anymore in FreeRTOS+TCP.
+ *
+ * THIS IS ONLY A DUMMY IMPLEMENTATION THAT RETURNS A PSEUDO RANDOM NUMBER SO IS
+ * NOT INTENDED FOR USE IN PRODUCTION SYSTEMS.
+ */
+BaseType_t xApplicationGetRandomNumber( uint32_t * pulNumber )
+{
+ *pulNumber = uxRand();
+ return pdTRUE;
+}
+/*-----------------------------------------------------------*/
+
+/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
+ * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
+ * used by the Idle task. */
+void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
+ StackType_t ** ppxIdleTaskStackBuffer,
+ uint32_t * pulIdleTaskStackSize )
+{
+ /* If the buffers to be provided to the Idle task are declared inside this
+ * function then they must be declared static - otherwise they will be allocated on
+ * the stack and so not exists after this function exits. */
+ static StaticTask_t xIdleTaskTCB;
+ static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
+
+ /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
+ * state will be stored. */
+ *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
+
+ /* Pass out the array that will be used as the Idle task's stack. */
+ *ppxIdleTaskStackBuffer = uxIdleTaskStack;
+
+ /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
+ * Note that, as the array is necessarily of type StackType_t,
+ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
+ *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
+}
+/*-----------------------------------------------------------*/
+
+/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
+ * application must provide an implementation of vApplicationGetTimerTaskMemory()
+ * to provide the memory that is used by the Timer service task. */
+void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
+ StackType_t ** ppxTimerTaskStackBuffer,
+ uint32_t * pulTimerTaskStackSize )
+{
+ /* If the buffers to be provided to the Timer task are declared inside this
+ * function then they must be declared static - otherwise they will be allocated on
+ * the stack and so not exists after this function exits. */
+ static StaticTask_t xTimerTaskTCB;
+ static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
+
+ /* Pass out a pointer to the StaticTask_t structure in which the Timer
+ * task's state will be stored. */
+ *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
+
+ /* Pass out the array that will be used as the Timer task's stack. */
+ *ppxTimerTaskStackBuffer = uxTimerTaskStack;
+
+ /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
+ * Note that, as the array is necessarily of type StackType_t,
+ * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
+ *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
+}
+/*-----------------------------------------------------------*/
diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Http_Demo_Helpers/http_demo_utils.c b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Http_Demo_Helpers/http_demo_utils.c
new file mode 100644
index 000000000..824c3131d
--- /dev/null
+++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Http_Demo_Helpers/http_demo_utils.c
@@ -0,0 +1,196 @@
+/*
+ * FreeRTOS Kernel V10.3.0
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* Standard includes. */
+#include <assert.h>
+
+#include "http_demo_utils.h"
+
+/* Exponential backoff retry include. */
+#include "exponential_backoff.h"
+
+/* Parser utilities. */
+#include "http_parser.h"
+
+/*-----------------------------------------------------------*/
+
+BaseType_t connectToServerWithBackoffRetries( TransportConnect_t connectFunction,
+ NetworkContext_t * pxNetworkContext )
+{
+ BaseType_t xReturn = pdFAIL;
+ /* Status returned by the retry utilities. */
+ RetryUtilsStatus_t xRetryUtilsStatus = RetryUtilsSuccess;
+ /* Struct containing the next backoff time. */
+ RetryUtilsParams_t xReconnectParams;
+
+ assert( connectFunction != NULL );
+
+ /* Initialize reconnect attempts and interval */
+ RetryUtils_ParamsReset( &xReconnectParams );
+ xReconnectParams.maxRetryAttempts = MAX_RETRY_ATTEMPTS;
+
+ /* Attempt to connect to the HTTP server. If connection fails, retry after a
+ * timeout. The timeout value will exponentially increase until either the
+ * maximum timeout value is reached or the set number of attempts are
+ * exhausted.*/
+ do
+ {
+ xReturn = connectFunction( pxNetworkContext );
+
+ if( xReturn != pdPASS )
+ {
+ LogWarn( ( "Connection to the HTTP server failed. "
+ "Retrying connection with backoff and jitter." ) );
+ LogInfo( ( "Retry attempt %lu out of maximum retry attempts %lu.",
+ ( xReconnectParams.attemptsDone + 1 ),
+ MAX_RETRY_ATTEMPTS ) );
+ xRetryUtilsStatus = RetryUtils_BackoffAndSleep( &xReconnectParams );
+ }
+ } while( ( xReturn == pdFAIL ) && ( xRetryUtilsStatus == RetryUtilsSuccess ) );
+
+ if( xReturn == pdFAIL )
+ {
+ LogError( ( "Connection to the server failed, all attempts exhausted." ) );
+ }
+
+ return xReturn;
+}
+
+/*-----------------------------------------------------------*/
+
+HTTPStatus_t getUrlPath( const char * pcUrl,
+ size_t xUrlLen,
+ const char ** pcPath,
+ size_t * pxPathLen )
+{
+ /* http-parser status. Initialized to 1 to signify failure. */
+ int lParserStatus = 1;
+ struct http_parser_url xUrlParser;
+ HTTPStatus_t xHTTPStatus = HTTPSuccess;
+
+ /* Sets all members in xUrlParser to 0. */
+ http_parser_url_init( &xUrlParser );
+
+ if( ( pcUrl == NULL ) || ( pcPath == NULL ) || ( pxPathLen == NULL ) )
+ {
+ LogError( ( "NULL parameter passed to getUrlPath()." ) );
+ xHTTPStatus = HTTPInvalidParameter;
+ }
+
+ if( xHTTPStatus == HTTPSuccess )
+ {
+ lParserStatus = http_parser_parse_url( pcUrl, xUrlLen, 0, &xUrlParser );
+
+ if( lParserStatus != 0 )
+ {
+ LogError( ( "Error parsing the input URL %.*s. Error code: %d.",
+ ( int32_t ) xUrlLen,
+ pcUrl,
+ lParserStatus ) );
+ xHTTPStatus = HTTPParserInternalError;
+ }
+ }
+
+ if( xHTTPStatus == HTTPSuccess )
+ {
+ *pxPathLen = ( size_t ) ( xUrlParser.field_data[ UF_PATH ].len );
+
+ if( *pxPathLen == 0 )
+ {
+ xHTTPStatus = HTTPNoResponse;
+ *pcPath = NULL;
+ }
+ else
+ {
+ *pcPath = &pcUrl[ xUrlParser.field_data[ UF_PATH ].off ];
+ }
+ }
+
+ if( xHTTPStatus != HTTPSuccess )
+ {
+ LogError( ( "Error parsing the path from URL %s. Error code: %d",
+ pcUrl,
+ xHTTPStatus ) );
+ }
+
+ return xHTTPStatus;
+}
+
+/*-----------------------------------------------------------*/
+
+HTTPStatus_t getUrlAddress( const char * pcUrl,
+ size_t xUrlLen,
+ const char ** pcAddress,
+ size_t * pxAddressLen )
+{
+ /* http-parser status. Initialized to 1 to signify failure. */
+ int lParserStatus = 1;
+ struct http_parser_url xUrlParser;
+ HTTPStatus_t xHTTPStatus = HTTPSuccess;
+
+ /* Sets all members in xUrlParser to 0. */
+ http_parser_url_init( &xUrlParser );
+
+ if( ( pcUrl == NULL ) || ( pcAddress == NULL ) || ( pxAddressLen == NULL ) )
+ {
+ LogError( ( "NULL parameter passed to getUrlAddress()." ) );
+ xHTTPStatus = HTTPInvalidParameter;
+ }
+
+ if( xHTTPStatus == HTTPSuccess )
+ {
+ lParserStatus = http_parser_parse_url( pcUrl, xUrlLen, 0, &xUrlParser );
+
+ if( lParserStatus != 0 )
+ {
+ LogError( ( "Error parsing the input URL %.*s. Error code: %d.",
+ ( int32_t ) xUrlLen,
+ pcUrl,
+ lParserStatus ) );
+ xHTTPStatus = HTTPParserInternalError;
+ }
+ }
+
+ if( xHTTPStatus == HTTPSuccess )
+ {
+ *pxAddressLen = ( size_t ) ( xUrlParser.field_data[ UF_HOST ].len );
+
+ if( *pxAddressLen == 0 )
+ {
+ xHTTPStatus = HTTPNoResponse;
+ *pcAddress = NULL;
+ }
+ else
+ {
+ *pcAddress = &pcUrl[ xUrlParser.field_data[ UF_HOST ].off ];
+ }
+ }
+
+ if( xHTTPStatus != HTTPSuccess )
+ {
+ LogError( ( "Error parsing the address from URL %s. Error code %d",
+ pcUrl,
+ xHTTPStatus ) );
+ }
+
+ return xHTTPStatus;
+}
diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Http_Demo_Helpers/http_demo_utils.h b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Http_Demo_Helpers/http_demo_utils.h
new file mode 100644
index 000000000..3d64421a2
--- /dev/null
+++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Http_Demo_Helpers/http_demo_utils.h
@@ -0,0 +1,126 @@
+/*
+ * FreeRTOS Kernel V10.3.0
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef HTTP_DEMO_UTILS_H
+#define HTTP_DEMO_UTILS_H
+
+/* Standard includes. */
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+
+/* Kernel includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+/* Transport interface implementation include header for TLS. */
+#include "using_mbedtls.h"
+
+/* HTTP API header. */
+#include "core_http_client.h"
+
+/**
+ * @brief Function pointer for establishing connection to a server.
+ *
+ * @param[out] pxNetworkContext Implementation-defined network context.
+ *
+ * @return pdFAIL on failure; pdPASS on successful connection.
+ */
+typedef BaseType_t ( * TransportConnect_t )( NetworkContext_t * pxNetworkContext );
+
+/**
+ * @brief Connect to a server with reconnection retries.
+ *
+ * If connection fails, retry is attempted after a timeout. The timeout value
+ * will exponentially increase until either the maximum timeout value is reached
+ * or the set number of attempts are exhausted.
+ *
+ * @param[in] connectFunction Function pointer for establishing connection to a
+ * server.
+ * @param[out] pxNetworkContext Implementation-defined network context.
+ *
+ * @return pdFAIL on failure; pdPASS on successful connection.
+ */
+BaseType_t connectToServerWithBackoffRetries( TransportConnect_t connectFunction,
+ NetworkContext_t * pxNetworkContext );
+
+/**
+ * @brief Retrieve the path from the input URL.
+ *
+ * This function retrieves the location and length of the path from within the
+ * input the URL. The query is not included in the length returned.
+ *
+ * The URL MUST start with "http://" or "https://" to find the path.
+ *
+ * For example, if pcUrl is:
+ * "https://www.somewebsite.com/path/to/item.txt?optionalquery=stuff"
+ *
+ * Then pcPath and pxPathLen will be the following:
+ * *pcPath = "/path/to/item.txt?optionalquery=stuff"
+ * *pxPathLen = 17
+ *
+ * @param[in] pcUrl URL string to parse.
+ * @param[in] xUrlLen The length of the URL string input.
+ * @param[out] pcPath pointer within input url that the path starts at.
+ * @param[out] pxPathLen Length of the path.
+ *
+ * @return The status of the parsing attempt:
+ * HTTPSuccess if the path was successfully parsed,
+ * HTTPParserInternalError if there was an error parsing the URL,
+ * or HTTPNoResponse if the path was not found.
+ */
+HTTPStatus_t getUrlPath( const char * pcUrl,
+ size_t xUrlLen,
+ const char ** pcPath,
+ size_t * pxPathLen );
+
+/**
+ * @brief Retrieve the Address from the input URL.
+ *
+ * This function retrieves the location and length of the address from within
+ * the input URL. The path and query are not included in the length returned.
+ *
+ * The URL MUST start with "http://" or "https://" to find the address.
+ *
+ * For example, if pcUrl is:
+ * "https://www.somewebsite.com/path/to/item.txt?optionalquery=stuff"
+ *
+ * Then pcAddress and pxAddressLen will be the following:
+ * *pcAddress = "www.somewebsite.com/path/to/item.txt?optionalquery=stuff"
+ * *pxAddressLen = 19
+ *
+ * @param[in] pcUrl URL string to parse.
+ * @param[in] xUrlLen The length of the URL string input.
+ * @param[out] pcAddress pointer within input url that the address starts at.
+ * @param[out] pxAddressLen Length of the address.
+ *
+ * @return The status of the parsing attempt:
+ * HTTPSuccess if the path was successfully parsed,
+ * HTTPParserInternalError if there was an error parsing the URL,
+ * or HTTPNoResponse if the path was not found.
+ */
+HTTPStatus_t getUrlAddress( const char * pcUrl,
+ size_t xUrlLen,
+ const char ** pcAddress,
+ size_t * pxAddressLen );
+
+#endif /* ifndef HTTP_DEMO_UTILS_H */
diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Http_Demo_Helpers/presigned_url_generator/README.md b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Http_Demo_Helpers/presigned_url_generator/README.md
new file mode 100644
index 000000000..db5fe1a81
--- /dev/null
+++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Http_Demo_Helpers/presigned_url_generator/README.md
@@ -0,0 +1,55 @@
+# Presigned S3 URLs Generator
+
+`presigned_url_gen.py` generates pre-signed URLs for S3 HTTP GET and PUT request access.
+
+### Dependencies
+
+* Python 3+
+* boto3
+* argparse
+
+### Prerequisites
+
+1. Install the dependencies.
+ ```sh
+ pip install boto3 argparse
+ ```
+
+1. You will need an AWS Account with S3 access before beginning. You must install and configure the AWS CLI in order to
+ use this script.
+ For information on AWS S3 please see: https://docs.aws.amazon.com/AmazonS3/latest/dev/Welcome.html
+ For AWS CLI installation information please see: https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html
+ For AWS CLI configuration information please see: https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html
+
+ ```sh
+ aws configure
+ ```
+
+### Usage
+
+1. Run `presigned_url_gen.py` with your s3 bucket name and s3 object key.
+ ```sh
+ ./presigned_urls_gen.py --bucket <YOUR BUCKET NAME> --key <YOUR OBJECT KEY>
+ ```
+ An example expected output:
+ ```
+ #define democonfigS3_PRESIGNED_GET_URL "https://aws-s3-endpoint/object-key.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ABABABABABABABABABAB%2F20201027%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20201027T194726Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=SomeHash12345UrlABcdEFgfIjK"
+ #define democonfigS3_PRESIGNED_PUT_URL "https://aws-s3-endpoint/object-key.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ABABABABABABABABABAB%2F20201027%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20201027T194726Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=SomeHash12345UrlLMnmOPqrStUvW"
+ ```
+1. Copy and paste the output to `demo_config.h` for macros `democonfigS3_PRESIGNED_GET_URL` and `democonfigS3_PRESIGNED_PUT_URL`.
+ ```c
+ #define democonfigS3_PRESIGNED_GET_URL "https://aws-s3-endpoint/object-key.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ABABABABABABABABABAB%2F20201027%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20201027T194726Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=SomeHash12345UrlABcdEFgfIjK"
+ #define democonfigS3_PRESIGNED_PUT_URL "https://aws-s3-endpoint/object-key.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ABABABABABABABABABAB%2F20201027%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20201027T194726Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=SomeHash12345UrlLMnmOPqrStUvW"
+ ```
+
+### Parameters
+
+#### --bucket
+The name of the S3 bucket from which the demo will download or upload.
+
+#### --key
+The name of the existing object you wish to download (GET),
+or the name of the object you wish to upload (PUT).
+
+#### --region
+Optional parameter for the AWS region in which the bucket is located. \ No newline at end of file
diff --git a/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Http_Demo_Helpers/presigned_url_generator/presigned_urls_gen.py b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Http_Demo_Helpers/presigned_url_generator/presigned_urls_gen.py
new file mode 100644
index 000000000..b829436e0
--- /dev/null
+++ b/FreeRTOS-Plus/Demo/coreHTTP_Windows_Simulator/Http_Demo_Helpers/presigned_url_generator/presigned_urls_gen.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python3
+
+import boto3
+from botocore.client import Config
+import argparse
+
+
+def get_presigned_urls(bucket_name, key_name, region_name) -> None:
+ """
+ Prints the presigned GET and PUT URLs assigned to the demo specific C
+ macros, for the given object key in the given S3 bucket. If the region
+ parameter is not defined, boto3 will use the one configured using AWS CLI.
+ The URLs are presigned with AWS's Signature Version 4.
+ Args:
+ bucket_name (str): S3 bucket
+ key_name (str): S3 object key
+ region_name (str): S3 bucket's region
+ """
+
+ # Get the service client.
+ # SigV2 is being deprecated. If the boto3 installation in the current Python environment has an older version of
+ # the package, then this configuration forces the use of SigV4.
+ s3 = boto3.client("s3", config=Config(signature_version="s3v4", region_name=region_name))
+
+ client_method_dict = {"GET": "get_object", "PUT": "put_object"}
+
+ # Generate the URL to get 'key-name' from 'bucket-name'
+ for method in client_method_dict.keys():
+ url = s3.generate_presigned_url(
+ ClientMethod=client_method_dict[method],
+ Params={"Bucket": bucket_name, "Key": key_name},
+ )
+ print("#define democonfigS3_PRESIGNED_" + method + "_URL" + " " + '"' + url + '"\n')
+
+
+def main():
+ """
+ Generate demo C macro strings, on the console, for the input S3 bucket and object key.
+ """
+ parser = argparse.ArgumentParser(description="S3 Presigned URL Generator. See README.md")
+ parser.add_argument(
+ "--bucket",
+ action="store",
+ required=True,
+ dest="bucket_name",
+ help="The name of the S3 bucket of interest.",
+ )
+ parser.add_argument(
+ "--key",
+ action="store",
+ required=True,
+ dest="key_name",
+ help="The name of the S3 Object in the bucket. This is referred to as a 'key'",
+ )
+ parser.add_argument(
+ "--region",
+ action="store",
+ required=False,
+ dest="region_name",
+ help="The region in which the S3 bucket of interest is created.",
+ )
+ args = parser.parse_args()
+
+ get_presigned_urls(args.bucket_name, args.key_name, args.region_name)
+
+
+if __name__ == "__main__": # pragma: no cover
+ main()
diff --git a/FreeRTOS-Plus/Source/Application-Protocols/coreHTTP b/FreeRTOS-Plus/Source/Application-Protocols/coreHTTP
new file mode 160000
+Subproject 0882657628eb7df12dc957f9b122601fd3054a6