\r
/* TCP/IP stack includes. */\r
#include "FreeRTOS_IP.h"\r
+#include "FreeRTOS_Sockets.h"\r
+\r
+/* Demo app includes. */\r
+#include "demo_logging.h"\r
+\r
+/* Set the following constants to 1 or 0 to define which tasks to include and\r
+exclude:\r
+\r
+mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS: When set to 1 two UDP client tasks\r
+and two UDP server tasks are created. The clients talk to the servers. One set\r
+of tasks use the standard sockets interface, and the other the zero copy sockets\r
+interface. These tasks are self checking and will trigger a configASSERT() if\r
+they detect a difference in the data that is received from that which was sent.\r
+As these tasks use UDP, and can therefore loose packets, they will cause\r
+configASSERT() to be called when they are run in a less than perfect networking\r
+environment.\r
+\r
+mainCREATE_SIMPLE_MQTT_EXAMPLE_TASKS: TBD\r
+*/\r
+#define mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS 1\r
+#define mainCREATE_SIMPLE_MQTT_EXAMPLE_TASKS 0\r
+\r
+/* Simple UDP client and server task parameters. */\r
+#define mainSIMPLE_UDP_CLIENT_SERVER_TASK_PRIORITY ( tskIDLE_PRIORITY )\r
+#define mainSIMPLE_UDP_CLIENT_SERVER_PORT ( 5005UL )\r
\r
/*\r
* Prototypes for the demos that can be started from this project.\r
*/\r
-extern void vStartSimpleTaskPoolDemo( void );\r
+extern void vStartSimpleMQTTDemo( void );\r
+extern void vStartSimpleUDPClientServerTasks( uint16_t usStackSize, uint32_t ulsPort, UBaseType_t uxPriority );\r
+\r
+/*\r
+ * Just seeds the simple pseudo random number generator.\r
+ *\r
+ * !!! NOTE !!!\r
+ * This is not a secure method of generating random numbers and production\r
+ * devices should use a true random number generator (TRNG).\r
+ */\r
+static void prvSRand( UBaseType_t ulSeed );\r
\r
-/* This example is the first in a sequence that adds IoT functionality into\r
-an existing TCP/IP project. In this first project the TCP/IP stack is not\r
-actually used, but it is still built, which requires this array to be\r
-present. */\r
+/*\r
+ * Miscellaneous initialisation including preparing the logging and seeding the\r
+ * random number generator.\r
+ */\r
+static void prvMiscInitialisation( void );\r
+\r
+/* The default IP and MAC address used by the demo. The address configuration\r
+defined here will be used if ipconfigUSE_DHCP is 0, or if ipconfigUSE_DHCP is\r
+1 but a DHCP server could not be contacted. See the online documentation for\r
+more information. */\r
+static const uint8_t ucIPAddress[ 4 ] = { configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 };\r
+static const uint8_t ucNetMask[ 4 ] = { configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 };\r
+static const uint8_t ucGatewayAddress[ 4 ] = { configGATEWAY_ADDR0, configGATEWAY_ADDR1, configGATEWAY_ADDR2, configGATEWAY_ADDR3 };\r
+static const uint8_t ucDNSServerAddress[ 4 ] = { configDNS_SERVER_ADDR0, configDNS_SERVER_ADDR1, configDNS_SERVER_ADDR2, configDNS_SERVER_ADDR3 };\r
+\r
+/* Set the following constant to pdTRUE to log using the method indicated by the\r
+name of the constant, or pdFALSE to not log using the method indicated by the\r
+name of the constant. Options include to standard out (xLogToStdout), to a disk\r
+file (xLogToFile), and to a UDP port (xLogToUDP). If xLogToUDP is set to pdTRUE\r
+then UDP messages are sent to the IP address configured as the echo server\r
+address (see the configECHO_SERVER_ADDR0 definitions in FreeRTOSConfig.h) and\r
+the port number set by configPRINT_PORT in FreeRTOSConfig.h. */\r
+const BaseType_t xLogToStdout = pdTRUE, xLogToFile = pdFALSE, xLogToUDP = pdFALSE;\r
+\r
+/* Default MAC address configuration. The demo creates a virtual network\r
+connection that uses this MAC address by accessing the raw Ethernet data\r
+to and from a real network connection on the host PC. See the\r
+configNETWORK_INTERFACE_TO_USE definition for information on how to configure\r
+the real network connection to use. */\r
const uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 };\r
\r
+/* Use by the pseudo random number generator. */\r
+static UBaseType_t ulNextRand;\r
/*-----------------------------------------------------------*/\r
\r
int main( void )\r
* TBD\r
*/\r
\r
- /* Create the example that demonstrates task pool functionality. Examples\r
- that demonstrate networking connectivity will be added in future projects\r
- and get started after the network has connected (from within the\r
- vApplicationIPNetworkEventHook() function).*/\r
- vStartSimpleTaskPoolDemo();\r
+ /* Miscellaneous initialisation including preparing the logging and seeding\r
+ the random number generator. */\r
+ prvMiscInitialisation();\r
\r
- /* Start the scheduler - if all is well from this point on only FreeRTOS\r
- tasks will execute. */\r
+ /* Initialise the network interface.\r
+\r
+ ***NOTE*** Tasks that use the network are created in the network event hook\r
+ when the network is connected and ready for use (see the implementation of\r
+ vApplicationIPNetworkEventHook() below). The address values passed in here\r
+ are used if ipconfigUSE_DHCP is set to 0, or if ipconfigUSE_DHCP is set to 1\r
+ but a DHCP server cannot be contacted. */\r
+ FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress );\r
+\r
+ /* Start the RTOS scheduler. */\r
vTaskStartScheduler();\r
\r
/* If all is well, the scheduler will now be running, and the following\r
events are only received if implemented in the MAC driver. */\r
void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )\r
{\r
- /* This example is the first in a sequence that adds IoT functionality into\r
- an existing TCP/IP project. In this first project the TCP/IP stack is not\r
- actually used, but it is still built, which requires this function to be\r
- present. For now this function does not need to do anything, so just ensure\r
- the unused parameters don't cause compiler warnings and that calls to this\r
- function are trapped by the debugger. */\r
- __debugbreak();\r
- ( void ) eNetworkEvent;\r
+uint32_t ulIPAddress, ulNetMask, ulGatewayAddress, ulDNSServerAddress;\r
+char cBuffer[ 16 ];\r
+static BaseType_t xTasksAlreadyCreated = pdFALSE;\r
+\r
+ /* If the network has just come up...*/\r
+ if( eNetworkEvent == eNetworkUp )\r
+ {\r
+ /* Create the tasks that use the IP stack if they have not already been\r
+ created. */\r
+ if( xTasksAlreadyCreated == pdFALSE )\r
+ {\r
+ #if( mainCREATE_SIMPLE_UDP_CLIENT_SERVER_TASKS == 1 )\r
+ {\r
+ vStartSimpleUDPClientServerTasks( configMINIMAL_STACK_SIZE, mainSIMPLE_UDP_CLIENT_SERVER_PORT, mainSIMPLE_UDP_CLIENT_SERVER_TASK_PRIORITY );\r
+ }\r
+ #endif\r
+\r
+ #if( mainCREATE_SIMPLE_MQTT_EXAMPLE_TASKS == 1 )\r
+ {\r
+ vStartSimpleMQTTDemo();\r
+ }\r
+ #endif\r
+\r
+ xTasksAlreadyCreated = pdTRUE;\r
+ }\r
+\r
+ /* Print out the network configuration, which may have come from a DHCP\r
+ server. */\r
+ FreeRTOS_GetAddressConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress );\r
+ FreeRTOS_inet_ntoa( ulIPAddress, cBuffer );\r
+ FreeRTOS_printf( ( "\r\n\r\nIP Address: %s\r\n", cBuffer ) );/*_RB_ Should use IoT libraries logging. */\r
+\r
+ FreeRTOS_inet_ntoa( ulNetMask, cBuffer );\r
+ FreeRTOS_printf( ( "Subnet Mask: %s\r\n", cBuffer ) );\r
+\r
+ FreeRTOS_inet_ntoa( ulGatewayAddress, cBuffer );\r
+ FreeRTOS_printf( ( "Gateway Address: %s\r\n", cBuffer ) );\r
+\r
+ FreeRTOS_inet_ntoa( ulDNSServerAddress, cBuffer );\r
+ FreeRTOS_printf( ( "DNS Server Address: %s\r\n\r\n\r\n", cBuffer ) );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+UBaseType_t uxRand( void )\r
+{\r
+const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL;\r
+\r
+ /*\r
+ * Utility function to generate a pseudo random number.\r
+ *\r
+ * !!!NOTE!!!\r
+ * This is not a secure method of generating a random number. Production\r
+ * devices should use a True Random Number Generator (TRNG).\r
+ */\r
+ ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;\r
+ return( ( int ) ( ulNextRand >> 16UL ) & 0x7fffUL );\r
}\r
/*-----------------------------------------------------------*/\r
\r
+static void prvSRand( UBaseType_t ulSeed )\r
+{\r
+ /* Utility function to seed the pseudo random number generator. */\r
+ ulNextRand = ulSeed;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvMiscInitialisation( void )\r
+{\r
+time_t xTimeNow;\r
+uint32_t ulLoggingIPAddress;\r
+\r
+ ulLoggingIPAddress = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, configECHO_SERVER_ADDR1, configECHO_SERVER_ADDR2, configECHO_SERVER_ADDR3 );\r
+ vLoggingInit( xLogToStdout, xLogToFile, xLogToUDP, ulLoggingIPAddress, configPRINT_PORT );\r
+\r
+ /* Seed the random number generator. */\r
+ time( &xTimeNow );\r
+ FreeRTOS_debug_printf( ( "Seed for randomiser: %lu\n", xTimeNow ) );\r
+ prvSRand( ( uint32_t ) xTimeNow );\r
+ FreeRTOS_debug_printf( ( "Random numbers: %08X %08X %08X %08X\n", ipconfigRAND32(), ipconfigRAND32(), ipconfigRAND32(), ipconfigRAND32() ) );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) || ( ipconfigDHCP_REGISTER_HOSTNAME == 1 )\r
+\r
+ const char *pcApplicationHostnameHook( void )\r
+ {\r
+ /* Assign the name "FreeRTOS" to this network node. This function will\r
+ be called during the DHCP: the machine will be registered with an IP\r
+ address plus this name. */\r
+ return mainHOST_NAME;\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+#if( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 )\r
+\r
+ BaseType_t xApplicationDNSQueryHook( const char *pcName )\r
+ {\r
+ BaseType_t xReturn;\r
+\r
+ /* Determine if a name lookup is for this node. Two names are given\r
+ to this node: that returned by pcApplicationHostnameHook() and that set\r
+ by mainDEVICE_NICK_NAME. */\r
+ if( _stricmp( pcName, pcApplicationHostnameHook() ) == 0 )\r
+ {\r
+ xReturn = pdPASS;\r
+ }\r
+ else if( _stricmp( pcName, mainDEVICE_NICK_NAME ) == 0 )\r
+ {\r
+ xReturn = pdPASS;\r
+ }\r
+ else\r
+ {\r
+ xReturn = pdFAIL;\r
+ }\r
+\r
+ return xReturn;\r
+ }\r
+\r
+#endif\r
+/*-----------------------------------------------------------*/\r
+\r
+/*\r
+ * Callback that provides the inputs necessary to generate a randomized TCP\r
+ * Initial Sequence Number per RFC 6528. THIS IS ONLY A DUMMY IMPLEMENTATION\r
+ * THAT RETURNS A PSEUDO RANDOM NUMBER SO IS NOT INTENDED FOR USE IN PRODUCTION\r
+ * SYSTEMS.\r
+ */\r
extern uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress,\r
uint16_t usSourcePort,\r
uint32_t ulDestinationAddress,\r
uint16_t usDestinationPort )\r
{\r
- /* This example is the first in a sequence that adds IoT functionality into\r
- an existing TCP/IP project. In this first project the TCP/IP stack is not\r
- actually used, but it is still built, which requires this function to be\r
- present. For now this function does not need to do anything, so just ensure\r
- the unused parameters don't cause compiler warnings and that calls to this\r
- function are trapped by the debugger. */\r
( void ) ulSourceAddress;\r
( void ) usSourcePort;\r
( void ) ulDestinationAddress;\r
( void ) usDestinationPort;\r
- __debugbreak();\r
- return 0;\r
-}\r
-/*-----------------------------------------------------------*/\r
\r
-UBaseType_t uxRand( void )\r
-{\r
- /* This example is the first in a sequence that adds IoT functionality into\r
- an existing TCP/IP project. In this first project the TCP/IP stack is not\r
- actually used, but it is still built, which requires this function to be\r
- present. For now this function does not need to do anything, so just ensure\r
- the calls to the function are trapped by the debugger. */\r
- __debugbreak();\r
- return 0;\r
+ return uxRand();\r
}\r
/*-----------------------------------------------------------*/\r
\r