]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS-Plus/Source/FreeRTOS-Plus-UDP/FreeRTOS_DHCP.c
FreeRTOS+UDP was removed in FreeRTOS V10.1.0 as it was replaced by FreeRTOS+TCP,
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-UDP / FreeRTOS_DHCP.c
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-UDP/FreeRTOS_DHCP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-UDP/FreeRTOS_DHCP.c
deleted file mode 100644 (file)
index 752e5dc..0000000
+++ /dev/null
@@ -1,728 +0,0 @@
-/*\r
- * FreeRTOS+UDP V1.0.4\r
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
- *\r
- * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
- * this software and associated documentation files (the "Software"), to deal in\r
- * the Software without restriction, including without limitation the rights to\r
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
- * the Software, and to permit persons to whom the Software is furnished to do so,\r
- * subject to the following conditions:\r
- *\r
- * The above copyright notice and this permission notice shall be included in all\r
- * copies or substantial portions of the Software.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
- *\r
- * http://www.FreeRTOS.org\r
- * http://aws.amazon.com/freertos\r
- *\r
- * 1 tab == 4 spaces!\r
- */\r
-\r
-/* Standard includes. */\r
-#include <stdint.h>\r
-\r
-/* FreeRTOS includes. */\r
-#include "FreeRTOS.h"\r
-#include "task.h"\r
-#include "queue.h"\r
-#include "timers.h"\r
-\r
-/* FreeRTOS+UDP includes. */\r
-#include "FreeRTOS_UDP_IP.h"\r
-#include "FreeRTOS_IP_Private.h"\r
-#include "FreeRTOS_DHCP.h"\r
-#include "FreeRTOS_Sockets.h"\r
-#include "NetworkInterface.h"\r
-#include "IPTraceMacroDefaults.h"\r
-\r
-/* Exclude the entire file if DHCP is not enabled. */\r
-#if ipconfigUSE_DHCP != 0\r
-\r
-#if ( ipconfigUSE_DHCP != 0 ) && ( ipconfigNETWORK_MTU < 586 )\r
-       /* DHCP must be able to receive an options field of 312 bytes, the fixed\r
-       part of the DHCP packet is 240 bytes, and the IP/UDP headers take 28 bytes. */\r
-       #error ipconfigNETWORK_MTU needs to be at least 586 to use DHCP (588 if ipconfigCAN_FRAGMENT_OUTGOING_PACKETS is set to 1)\r
-#endif\r
-\r
-/* Parameter widths in the DHCP packet. */\r
-#define dhcpCLIENT_HARDWARE_ADDRESS_LENGTH             16\r
-#define dhcpSERVER_HOST_NAME_LENGTH                            64\r
-#define dhcpBOOT_FILE_NAME_LENGTH                              128\r
-\r
-/* Timer parameters.  Windows simulator times are much shorter because simulated\r
-time is not real time. */\r
-#ifdef _WINDOWS_\r
-       #define dhcpINITIAL_DHCP_TX_PERIOD                      ( 100 / portTICK_RATE_MS )\r
-       #define dhcpINITIAL_TIMER_PERIOD                        ( 10 / portTICK_RATE_MS )\r
-       #define dhcpMAX_TIME_TO_WAIT_FOR_ACK            ( 200 / portTICK_RATE_MS )\r
-#else\r
-       #define dhcpINITIAL_DHCP_TX_PERIOD                      ( 5000 / portTICK_RATE_MS )\r
-       #define dhcpINITIAL_TIMER_PERIOD                        ( 250 / portTICK_RATE_MS )\r
-       #define dhcpMAX_TIME_TO_WAIT_FOR_ACK            ( 5000 / portTICK_RATE_MS )\r
-#endif /* _WINDOWS_ */\r
-\r
-/* Codes of interest found in the DHCP options field. */\r
-#define dhcpSUBNET_MASK_OPTION_CODE                            ( 1 )\r
-#define dhcpGATEWAY_OPTION_CODE                                        ( 3 )\r
-#define hdcpDNS_SERVER_OPTIONS_CODE                            ( 6 )\r
-#define dhcpMESSAGE_TYPE_OPTION_CODE                   ( 53 )\r
-#define dhcpLEASE_TIME_OPTION_CODE                             ( 51 )\r
-#define dhcpCLIENT_IDENTIFIER_OPTION_CODE              ( 61 )\r
-#define dhcpPARAMETER_REQUEST_OPTION_CODE              ( 55 )\r
-#define dhcpREQUEST_IP_ADDRESS_OPTION_CODE             ( 50 )\r
-#define dhcpSERVER_IP_ADDRESS_OPTION_CODE              ( 54 )\r
-\r
-/* The four DHCP message types of interest. */\r
-#define dhcpMESSAGE_TYPE_DISCOVER                              ( 1 )\r
-#define dhcpMESSAGE_TYPE_OFFER                                 ( 2 )\r
-#define dhcpMESSAGE_TYPE_REQUEST                               ( 3 )\r
-#define dhcpMESSAGE_TYPE_ACK                                   ( 5 )\r
-#define dhcpMESSAGE_TYPE_NACK                                  ( 6 )\r
-\r
-/* Offsets into the transmitted DHCP options fields at which various parameters\r
-are located. */\r
-#define dhcpCLIENT_IDENTIFIER_OFFSET                   ( 5 )\r
-#define dhcpREQUESTED_IP_ADDRESS_OFFSET                        ( 13 )\r
-#define dhcpDHCP_SERVER_IP_ADDRESS_OFFSET              ( 19 )\r
-\r
-/* Values used in the DHCP packets. */\r
-#define dhcpREQUEST_OPCODE                                             ( 1 )\r
-#define dhcpREPLY_OPCODE                                               ( 2 )\r
-#define dhcpADDRESS_TYPE_ETHERNET                              ( 1 )\r
-#define dhcpETHERNET_ADDRESS_LENGTH                            ( 6 )\r
-\r
-/* If a lease time is not received, use the default of two days. */\r
-#define dhcpDEFAULT_LEASE_TIME                                 ( ( 48UL * 60UL * 60UL * 1000UL ) / portTICK_RATE_MS ) /* 48 hours in ticks. */\r
-\r
-/* Don't allow the lease time to be too short. */\r
-#define dhcpMINIMUM_LEASE_TIME                                 ( 60000UL / portTICK_RATE_MS )  /* 60 seconds in ticks. */\r
-\r
-/* Marks the end of the variable length options field in the DHCP packet. */\r
-#define dhcpOPTION_END_BYTE 0xff\r
-\r
-/* Offset into a DHCP message at which the first byte of the options is\r
-located. */\r
-#define dhcpFIRST_OPTION_BYTE_OFFSET                   ( 0xf0 )\r
-\r
-/* When walking the variable length options field, the following value is used\r
-to ensure the walk has not gone past the end of the valid options.  2 bytes is\r
-made up of the length byte, and minimum one byte value. */\r
-#define dhcpMAX_OPTION_LENGTH_OF_INTEREST              ( 2L )\r
-\r
-/* Standard DHCP port numbers and magic cookie value. */\r
-#if( ipconfigBYTE_ORDER == FREERTOS_LITTLE_ENDIAN )\r
-       #define dhcpCLIENT_PORT 0x4400\r
-       #define dhcpSERVER_PORT 0x4300\r
-       #define dhcpCOOKIE              0x63538263\r
-       #define dhcpBROADCAST   0x0080\r
-#else\r
-       #define dhcpCLIENT_PORT 0x0044\r
-       #define dhcpSERVER_PORT 0x0043\r
-       #define dhcpCOOKIE              0x63825363\r
-       #define dhcpBROADCAST   0x8000\r
-#endif /* ipconfigBYTE_ORDER */\r
-\r
-#include "pack_struct_start.h"\r
-struct xDHCPMessage\r
-{\r
-       uint8_t ucOpcode;\r
-       uint8_t ucAddressType;\r
-       uint8_t ucAddressLength;\r
-       uint8_t ucHops;\r
-       uint32_t ulTransactionID;\r
-       uint16_t usElapsedTime;\r
-       uint16_t usFlags;\r
-       uint32_t ulClientIPAddress_ciaddr;\r
-       uint32_t ulYourIPAddress_yiaddr;\r
-       uint32_t ulServerIPAddress_siaddr;\r
-       uint32_t ulRelayAgentIPAddress_giaddr;\r
-       uint8_t ucClientHardwareAddress[ dhcpCLIENT_HARDWARE_ADDRESS_LENGTH ];\r
-       uint8_t ucServerHostName[ dhcpSERVER_HOST_NAME_LENGTH ];\r
-       uint8_t ucBootFileName[ dhcpBOOT_FILE_NAME_LENGTH ];\r
-       uint32_t ulDHCPCookie;\r
-       uint8_t ucFirstOptionByte;\r
-}\r
-#include "pack_struct_end.h"\r
-typedef struct xDHCPMessage xDHCPMessage_t;\r
-\r
-/* DHCP state machine states. */\r
-typedef enum\r
-{\r
-       eWaitingSendFirstDiscover = 0,  /* Initial state.  Send a discover the first time it is called, and reset all timers. */\r
-       eWaitingOffer,                                  /* Either resend the discover, or, if the offer is forthcoming, send a request. */\r
-       eWaitingAcknowledge,                    /* Either resend the request. */\r
-       eLeasedAddress,                                 /* Resend the request at the appropriate time to renew the lease. */\r
-       eNotUsingLeasedAddress                  /* DHCP failed, and a default IP address is being used. */\r
-} eDHCPState_t;\r
-\r
-/*\r
- * Generate a DHCP discover message and send it on the DHCP socket.\r
- */\r
-static void prvSendDHCPDiscover( xMACAddress_t *pxMACAddress );\r
-\r
-/*\r
- * Interpret message received on the DHCP socket.\r
- */\r
-static BaseType_t prvProcessDHCPReplies( uint8_t ucExpectedMessageType, xMACAddress_t *pxMACAddress, xNetworkAddressingParameters_t *pxNetworkAddressing );\r
-\r
-/*\r
- * Generate a DHCP request packet, and send it on the DHCP socket.\r
- */\r
-static void prvSendDHCPRequest( xMACAddress_t *pxMACAddress );\r
-\r
-/*\r
- * Prepare to start a DHCP transaction.  This initialises some state variables\r
- * and creates the DHCP socket if necessary.\r
- */\r
-static void prvInitialiseDHCP( void );\r
-\r
-/*\r
- * Creates the part of outgoing DHCP messages that are common to all outgoing\r
- * DHCP messages.\r
- */\r
-static uint8_t *prvCreatePartDHCPMessage( struct freertos_sockaddr *pxAddress, xMACAddress_t *pxMACAddress, uint8_t ucOpcode, const uint8_t * const pucOptionsArray, size_t xOptionsArraySize );\r
-\r
-/*\r
- * Create the DHCP socket, if it has not been created already.\r
- */\r
-static void prvCreateDHCPSocket( void );\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/* The timer used to drive the DHCP state machine. */\r
-static xTimerHandle xDHCPTimer = NULL;\r
-\r
-/* The UDP socket used for all incoming and outgoing DHCP traffic. */\r
-static xSocket_t xDHCPSocket = NULL;\r
-\r
-/* Hold information in between steps in the DHCP state machine. */\r
-static uint32_t ulTransactionId = 0UL, ulOfferedIPAddress = 0UL, ulDHCPServerAddress = 0UL, ulLeaseTime = 0;\r
-\r
-/* Hold information on the current timer state. */\r
-static TickType_t xDHCPTxTime = 0x00, xDHCPTxPeriod = 0x00;\r
-\r
-/* Maintains the DHCP state machine state. */\r
-static eDHCPState_t eDHCPState = eWaitingSendFirstDiscover;\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void vDHCPProcess( BaseType_t xReset, xMACAddress_t *pxMACAddress, uint32_t *pulIPAddress, xNetworkAddressingParameters_t *pxNetworkAddressing )\r
-{\r
-       if( xReset != pdFALSE )\r
-       {\r
-               eDHCPState = eWaitingSendFirstDiscover;\r
-       }\r
-\r
-       switch( eDHCPState )\r
-       {\r
-               case eWaitingSendFirstDiscover :\r
-\r
-                       /* Initial state.  Create the DHCP socket, timer, etc. if they\r
-                       have not already been created. */\r
-                       prvInitialiseDHCP();\r
-                       *pulIPAddress = 0UL;\r
-\r
-                       /* Send the first discover request. */\r
-                       if( xDHCPSocket != NULL )\r
-                       {\r
-                               xDHCPTxTime = xTaskGetTickCount();\r
-                               prvSendDHCPDiscover( pxMACAddress );\r
-                               eDHCPState = eWaitingOffer;\r
-                       }\r
-                       break;\r
-\r
-               case eWaitingOffer :\r
-\r
-                       /* Look for offers coming in. */\r
-                       if( prvProcessDHCPReplies( dhcpMESSAGE_TYPE_OFFER, pxMACAddress, pxNetworkAddressing ) == pdPASS )\r
-                       {\r
-                               /* An offer has been made, generate the request. */\r
-                               xDHCPTxTime = xTaskGetTickCount();\r
-                               xDHCPTxPeriod = dhcpINITIAL_DHCP_TX_PERIOD;\r
-                               prvSendDHCPRequest( pxMACAddress );\r
-                               eDHCPState = eWaitingAcknowledge;\r
-                       }\r
-                       else\r
-                       {\r
-                               /* Is it time to send another Discover? */\r
-                               if( ( xTaskGetTickCount() - xDHCPTxTime ) > xDHCPTxPeriod )\r
-                               {\r
-                                       /* Increase the time period, and if it has not got to the\r
-                                       point of giving up - send another discovery. */\r
-                                       xDHCPTxPeriod <<= 1;\r
-                                       if( xDHCPTxPeriod <= ipconfigMAXIMUM_DISCOVER_TX_PERIOD )\r
-                                       {\r
-                                               ulTransactionId++;\r
-                                               xDHCPTxTime = xTaskGetTickCount();\r
-                                               prvSendDHCPDiscover( pxMACAddress );\r
-                                       }\r
-                                       else\r
-                                       {\r
-                                               /* Revert to static IP address. */\r
-                                               taskENTER_CRITICAL();\r
-                                               {\r
-                                                       *pulIPAddress = pxNetworkAddressing->ulDefaultIPAddress;\r
-                                                       iptraceDHCP_REQUESTS_FAILED_USING_DEFAULT_IP_ADDRESS( pxNetworkAddressing->ulDefaultIPAddress );\r
-                                               }\r
-                                               taskEXIT_CRITICAL();\r
-                                               eDHCPState = eNotUsingLeasedAddress;\r
-                                               xTimerStop( xDHCPTimer, ( TickType_t ) 0 );\r
-\r
-                                               #if ipconfigUSE_NETWORK_EVENT_HOOK == 1\r
-                                               {\r
-                                                       vApplicationIPNetworkEventHook( eNetworkUp );\r
-                                               }\r
-                                               #endif\r
-\r
-                                               /* Static configuration is being used, so the network is now up. */\r
-                                               #if ipconfigFREERTOS_PLUS_NABTO == 1\r
-                                               {\r
-                                                       /* Return value is used in configASSERT() inside the\r
-                                                       function. */\r
-                                                       ( void ) xStartNabtoTask();\r
-                                               }\r
-                                               #endif /* ipconfigFREERTOS_PLUS_NABTO */\r
-\r
-                                               /* Close socket to ensure packets don't queue on it. */\r
-                                               FreeRTOS_closesocket( xDHCPSocket );\r
-                                               xDHCPSocket = NULL;\r
-                                       }\r
-                               }\r
-                       }\r
-                       break;\r
-\r
-               case eWaitingAcknowledge :\r
-\r
-                       /* Look for acks coming in. */\r
-                       if( prvProcessDHCPReplies( dhcpMESSAGE_TYPE_ACK, pxMACAddress, pxNetworkAddressing ) == pdPASS )\r
-                       {\r
-                               /* DHCP completed.  The IP address can now be used, and the\r
-                               timer set to the lease timeout time. */\r
-                               *pulIPAddress = ulOfferedIPAddress;\r
-                               eDHCPState = eLeasedAddress;\r
-\r
-                               #if ipconfigUSE_NETWORK_EVENT_HOOK == 1\r
-                               {\r
-                                       vApplicationIPNetworkEventHook( eNetworkUp );\r
-                               }\r
-                               #endif\r
-\r
-                               /* Static configuration is being used, so the network is now\r
-                               up. */\r
-                               #if ipconfigFREERTOS_PLUS_NABTO == 1\r
-                               {\r
-                                       /* Return value is used in configASSERT() inside the\r
-                                       function. */\r
-                                       ( void ) xStartNabtoTask();\r
-                               }\r
-                               #endif /* ipconfigFREERTOS_PLUS_NABTO */\r
-\r
-                               /* Close socket to ensure packets don't queue on it. */\r
-                               FreeRTOS_closesocket( xDHCPSocket );\r
-                               xDHCPSocket = NULL;\r
-\r
-                               if( ulLeaseTime == 0UL )\r
-                               {\r
-                                       ulLeaseTime = dhcpDEFAULT_LEASE_TIME;\r
-                               }\r
-                               else if( ulLeaseTime < dhcpMINIMUM_LEASE_TIME )\r
-                               {\r
-                                       ulLeaseTime = dhcpMINIMUM_LEASE_TIME;\r
-                               }\r
-                               else\r
-                               {\r
-                                       /* The lease time is already valid. */\r
-                               }\r
-\r
-                               xTimerChangePeriod( xDHCPTimer, ulLeaseTime, portMAX_DELAY );\r
-                       }\r
-                       else\r
-                       {\r
-                               /* Is it time to send another Discover? */\r
-                               if( ( xTaskGetTickCount() - xDHCPTxTime ) > xDHCPTxPeriod )\r
-                               {\r
-                                       /* Increase the time period, and if it has not got to the\r
-                                       point of giving up - send another request. */\r
-                                       xDHCPTxPeriod <<= 1;\r
-                                       if( xDHCPTxPeriod <= ipconfigMAXIMUM_DISCOVER_TX_PERIOD )\r
-                                       {\r
-                                               xDHCPTxTime = xTaskGetTickCount();\r
-                                               prvSendDHCPRequest( pxMACAddress );\r
-                                       }\r
-                                       else\r
-                                       {\r
-                                               /* Give up, start again. */\r
-                                               eDHCPState = eWaitingSendFirstDiscover;\r
-                                       }\r
-                               }\r
-                       }\r
-                       break;\r
-\r
-               case eLeasedAddress :\r
-\r
-                       /* Resend the request at the appropriate time to renew the lease. */\r
-                       prvCreateDHCPSocket();\r
-                       if( xDHCPSocket != NULL )\r
-                       {\r
-                               xDHCPTxTime = xTaskGetTickCount();\r
-                               xDHCPTxPeriod = dhcpINITIAL_DHCP_TX_PERIOD;\r
-                               prvSendDHCPRequest( pxMACAddress );\r
-                               eDHCPState = eWaitingAcknowledge;\r
-                       }\r
-                       xTimerChangePeriod( xDHCPTimer, dhcpINITIAL_TIMER_PERIOD, portMAX_DELAY );\r
-                       break;\r
-\r
-               case eNotUsingLeasedAddress:\r
-                       xTimerStop( xDHCPTimer, ( TickType_t ) 0 );\r
-                       break;\r
-       }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvCreateDHCPSocket( void )\r
-{\r
-struct freertos_sockaddr xAddress;\r
-BaseType_t xReturn;\r
-TickType_t xTimeoutTime = 0;\r
-\r
-       /* Create the socket, if it has not already been created. */\r
-       if( xDHCPSocket == NULL )\r
-       {\r
-               xDHCPSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );\r
-               configASSERT( ( xDHCPSocket != FREERTOS_INVALID_SOCKET ) );\r
-\r
-               /* Ensure the Rx and Tx timeouts are zero as the DHCP executes in the\r
-               context of the IP task. */\r
-               FreeRTOS_setsockopt( xDHCPSocket, 0, FREERTOS_SO_RCVTIMEO, ( void * ) &xTimeoutTime, sizeof( TickType_t ) );\r
-               FreeRTOS_setsockopt( xDHCPSocket, 0, FREERTOS_SO_SNDTIMEO, ( void * ) &xTimeoutTime, sizeof( TickType_t ) );\r
-\r
-               /* Bind to the standard DHCP client port. */\r
-               xAddress.sin_port = dhcpCLIENT_PORT;\r
-               xReturn = FreeRTOS_bind( xDHCPSocket, &xAddress, sizeof( xAddress ) );\r
-               configASSERT( xReturn == 0 );\r
-\r
-               /* Remove compiler warnings if configASSERT() is not defined. */\r
-               ( void ) xReturn;\r
-       }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvInitialiseDHCP( void )\r
-{\r
-extern void vIPFunctionsTimerCallback( xTimerHandle xTimer );\r
-\r
-       /* Initialise the parameters that will be set by the DHCP process. */\r
-       if( ulTransactionId == 0 )\r
-       {\r
-               ulTransactionId = ipconfigRAND32();\r
-       }\r
-       else\r
-       {\r
-               ulTransactionId++;\r
-       }\r
-       ulOfferedIPAddress = 0UL;\r
-       ulDHCPServerAddress = 0UL;\r
-       xDHCPTxPeriod = dhcpINITIAL_DHCP_TX_PERIOD;\r
-\r
-       /* Create the DHCP socket if it has not already been created. */\r
-       prvCreateDHCPSocket();\r
-\r
-       if( xDHCPTimer == NULL )\r
-       {\r
-               xDHCPTimer = xTimerCreate( "DHCP", dhcpINITIAL_TIMER_PERIOD, pdTRUE, ( void * ) eDHCPEvent, vIPFunctionsTimerCallback );\r
-               configASSERT( xDHCPTimer );\r
-               xTimerStart( xDHCPTimer, portMAX_DELAY );\r
-       }\r
-       else\r
-       {\r
-               xTimerChangePeriod( xDHCPTimer, dhcpINITIAL_TIMER_PERIOD, portMAX_DELAY );\r
-       }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static BaseType_t prvProcessDHCPReplies( uint8_t ucExpectedMessageType, xMACAddress_t *pxMACAddress, xNetworkAddressingParameters_t *pxNetworkAddressing )\r
-{\r
-uint8_t *pucUDPPayload, *pucLastByte;\r
-struct freertos_sockaddr xClient;\r
-uint32_t xClientLength = sizeof( xClient );\r
-int32_t lBytes;\r
-xDHCPMessage_t *pxDHCPMessage;\r
-uint8_t *pucByte, ucOptionCode, ucLength;\r
-uint32_t ulProcessed;\r
-BaseType_t xReturn = pdFALSE;\r
-const uint32_t ulMandatoryOptions = 2; /* DHCP server address, and the correct DHCP message type must be present in the options. */\r
-\r
-       lBytes = FreeRTOS_recvfrom( xDHCPSocket, ( void * ) &pucUDPPayload, 0, FREERTOS_ZERO_COPY, &xClient, &xClientLength );\r
-\r
-       if( lBytes > 0 )\r
-       {\r
-               /* Map a DHCP structure onto the received data. */\r
-               pxDHCPMessage = ( xDHCPMessage_t * ) ( pucUDPPayload );\r
-\r
-               /* Sanity check. */\r
-               if( ( pxDHCPMessage->ulDHCPCookie == dhcpCOOKIE ) && ( pxDHCPMessage->ucOpcode == dhcpREPLY_OPCODE ) && ( pxDHCPMessage->ulTransactionID == ulTransactionId ) )\r
-               {\r
-                       if( memcmp( ( void * ) &( pxDHCPMessage->ucClientHardwareAddress ), ( void * ) pxMACAddress, sizeof( xMACAddress_t ) ) == 0 )\r
-                       {\r
-                               /* None of the essential options have been processed yet. */\r
-                               ulProcessed = 0;\r
-\r
-                               /* Walk through the options until the dhcpOPTION_END_BYTE byte\r
-                               is found, taking care not to walk off the end of the options. */\r
-                               pucByte = &( pxDHCPMessage->ucFirstOptionByte );\r
-                               pucLastByte = &( pucUDPPayload[ lBytes - dhcpMAX_OPTION_LENGTH_OF_INTEREST ] );\r
-                               while( ( *pucByte != dhcpOPTION_END_BYTE ) && ( pucByte < pucLastByte ) )\r
-                               {\r
-                                       ucOptionCode = *pucByte;\r
-                                       pucByte++;\r
-                                       ucLength = *pucByte;\r
-                                       pucByte++;\r
-\r
-                                       switch( ucOptionCode )\r
-                                       {\r
-                                               case dhcpMESSAGE_TYPE_OPTION_CODE       :\r
-\r
-                                                       if( *pucByte == ucExpectedMessageType )\r
-                                                       {\r
-                                                               /* The message type is the message type the\r
-                                                               state machine is expecting. */\r
-                                                               ulProcessed++;\r
-                                                       }\r
-                                                       else if( *pucByte == dhcpMESSAGE_TYPE_NACK )\r
-                                                       {\r
-                                                               if( ucExpectedMessageType == dhcpMESSAGE_TYPE_ACK )\r
-                                                               {\r
-                                                                       /* Start again. */\r
-                                                                       eDHCPState = eWaitingSendFirstDiscover;\r
-                                                               }\r
-                                                       }\r
-                                                       else\r
-                                                       {\r
-                                                               /* Don't process other message types. */\r
-                                                       }\r
-                                                       break;\r
-\r
-                                               case dhcpSUBNET_MASK_OPTION_CODE :\r
-\r
-                                                       if( ucLength == sizeof( uint32_t ) )\r
-                                                       {\r
-                                                               memcpy( ( void * ) &( pxNetworkAddressing->ulNetMask ), ( void * ) pucByte, ( size_t ) ucLength );\r
-                                                       }\r
-                                                       break;\r
-\r
-                                               case dhcpGATEWAY_OPTION_CODE :\r
-\r
-                                                       if( ucLength == sizeof( uint32_t ) )\r
-                                                       {\r
-                                                               /* ulProcessed is not incremented in this case\r
-                                                               because the gateway is not essential. */\r
-                                                               memcpy( ( void * ) &( pxNetworkAddressing->ulGatewayAddress ), ( void * ) pucByte, ( size_t ) ucLength );\r
-                                                       }\r
-                                                       break;\r
-\r
-                                               case hdcpDNS_SERVER_OPTIONS_CODE :\r
-\r
-                                                       /* ulProcessed is not incremented in this case\r
-                                                       because the DNS server is not essential.  Only the\r
-                                                       first DNS server address is taken. */\r
-                                                       memcpy( ( void * ) &( pxNetworkAddressing->ulDNSServerAddress ), ( void * ) pucByte, sizeof( uint32_t ) );\r
-                                                       break;\r
-\r
-                                               case dhcpSERVER_IP_ADDRESS_OPTION_CODE :\r
-\r
-                                                       if( ucLength == sizeof( uint32_t ) )\r
-                                                       {\r
-                                                               if( ucExpectedMessageType == dhcpMESSAGE_TYPE_OFFER )\r
-                                                               {\r
-                                                                       /* Offers state the replying server. */\r
-                                                                       ulProcessed++;\r
-                                                                       memcpy( ( void * ) &ulDHCPServerAddress, ( void * ) pucByte, ( size_t ) ucLength );\r
-                                                               }\r
-                                                               else\r
-                                                               {\r
-                                                                       /* The ack must come from the expected server. */\r
-                                                                       if( memcmp( ( void * ) &ulDHCPServerAddress, ( void * ) pucByte, ( size_t ) ucLength ) == 0 )\r
-                                                                       {\r
-                                                                               ulProcessed++;\r
-                                                                       }\r
-                                                               }\r
-                                                       }\r
-                                                       break;\r
-\r
-                                               case dhcpLEASE_TIME_OPTION_CODE :\r
-\r
-                                                       if( ucLength == sizeof( &ulLeaseTime ) )\r
-                                                       {\r
-                                                               /* ulProcessed is not incremented in this case\r
-                                                               because the lease time is not essential. */\r
-                                                               memcpy( ( void * ) &ulLeaseTime, ( void * ) pucByte, ( size_t ) ucLength );\r
-                                                               ulLeaseTime = FreeRTOS_ntohl( ulLeaseTime );\r
-\r
-                                                               /* Convert the lease time to milliseconds\r
-                                                               (*1000) then ticks (/portTICK_RATE_MS). */\r
-                                                               ulLeaseTime *= ( 1000UL / portTICK_RATE_MS );\r
-\r
-                                                               /* Divide the lease time to ensure a renew\r
-                                                               request is sent before the lease actually\r
-                                                               expires. */\r
-                                                               ulLeaseTime >>= 1UL;\r
-                                                       }\r
-                                                       break;\r
-\r
-                                               default :\r
-\r
-                                                       /* Not interested in this field. */\r
-\r
-                                                       break;\r
-                                       }\r
-\r
-                                       /* Jump over the data to find the next option code. */\r
-                                       if( ucLength == 0 )\r
-                                       {\r
-                                               break;\r
-                                       }\r
-                                       else\r
-                                       {\r
-                                               pucByte += ucLength;\r
-                                       }\r
-                               }\r
-\r
-                               /* Were all the mandatory options received? */\r
-                               if( ulProcessed == ulMandatoryOptions )\r
-                               {\r
-                                       ulOfferedIPAddress = pxDHCPMessage->ulYourIPAddress_yiaddr;\r
-                                       xReturn = pdPASS;\r
-                               }\r
-                       }\r
-               }\r
-\r
-               FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayload );\r
-       }\r
-\r
-       return xReturn;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static uint8_t *prvCreatePartDHCPMessage( struct freertos_sockaddr *pxAddress, xMACAddress_t *pxMACAddress, uint8_t ucOpcode, const uint8_t * const pucOptionsArray, size_t xOptionsArraySize )\r
-{\r
-xDHCPMessage_t *pxDHCPMessage;\r
-const size_t xRequiredBufferSize = sizeof( xDHCPMessage_t ) + xOptionsArraySize;\r
-uint8_t *pucUDPPayloadBuffer;\r
-static uint8_t ucUseBroadcastFlag = pdFALSE;\r
-\r
-       /* Get a buffer.  This uses a maximum delay, but the delay will be capped\r
-       to ipconfigMAX_SEND_BLOCK_TIME_TICKS so the return value still needs to be\r
-       test. */\r
-       do\r
-       {\r
-       }while( ( pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer( xRequiredBufferSize, portMAX_DELAY ) ) == NULL );\r
-\r
-       pxDHCPMessage = ( xDHCPMessage_t * ) pucUDPPayloadBuffer;\r
-\r
-       /* Most fields need to be zero. */\r
-       memset( ( void * ) pxDHCPMessage, 0x00, sizeof( xDHCPMessage_t ) );\r
-\r
-       /* Create the message. */\r
-       pxDHCPMessage->ucOpcode = ucOpcode;\r
-       pxDHCPMessage->ucAddressType = dhcpADDRESS_TYPE_ETHERNET;\r
-       pxDHCPMessage->ucAddressLength = dhcpETHERNET_ADDRESS_LENGTH;\r
-       pxDHCPMessage->ulTransactionID = ulTransactionId;\r
-       pxDHCPMessage->ulDHCPCookie = dhcpCOOKIE;\r
-\r
-       /* For maximum possibility of success, alternate between broadcast and non\r
-       broadcast. */\r
-       ucUseBroadcastFlag = !ucUseBroadcastFlag;\r
-       if( ucUseBroadcastFlag == pdTRUE )\r
-       {\r
-               pxDHCPMessage->usFlags = dhcpBROADCAST;\r
-       }\r
-       else\r
-       {\r
-               pxDHCPMessage->usFlags = 0;\r
-       }\r
-\r
-       memcpy( ( void * ) &( pxDHCPMessage->ucClientHardwareAddress[ 0 ] ), ( void * ) pxMACAddress, sizeof( xMACAddress_t ) );\r
-\r
-       /* Copy in the const part of the options options. */\r
-       memcpy( ( void * ) &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET ] ), ( void * ) pucOptionsArray, xOptionsArraySize );\r
-\r
-       /* Map in the client identifier. */\r
-       memcpy( ( void * ) &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET + dhcpCLIENT_IDENTIFIER_OFFSET ] ), ( void * ) pxMACAddress, sizeof( xMACAddress_t ) );\r
-\r
-       /* Set the addressing. */\r
-       pxAddress->sin_addr = ipBROADCAST_IP_ADDRESS;\r
-       pxAddress->sin_port = ( uint16_t ) dhcpSERVER_PORT;\r
-\r
-       return pucUDPPayloadBuffer;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvSendDHCPRequest( xMACAddress_t *pxMACAddress )\r
-{\r
-uint8_t *pucUDPPayloadBuffer;\r
-struct freertos_sockaddr xAddress;\r
-static const uint8_t ucDHCPRequestOptions[] =\r
-{\r
-       /* Do not change the ordering without also changing\r
-       dhcpCLIENT_IDENTIFIER_OFFSET, dhcpREQUESTED_IP_ADDRESS_OFFSET and\r
-       dhcpDHCP_SERVER_IP_ADDRESS_OFFSET. */\r
-       dhcpMESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_REQUEST,              /* Message type option. */\r
-       dhcpCLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0,                 /* Client identifier. */\r
-       dhcpREQUEST_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0,                              /* The IP address being requested. */\r
-       dhcpSERVER_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0,                               /* The IP address of the DHCP server. */\r
-       dhcpOPTION_END_BYTE\r
-};\r
-\r
-       pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, pxMACAddress, dhcpREQUEST_OPCODE, ucDHCPRequestOptions, sizeof( ucDHCPRequestOptions ) );\r
-\r
-       /* Copy in the IP address being requested. */\r
-       memcpy( ( void * ) &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET + dhcpREQUESTED_IP_ADDRESS_OFFSET ] ), ( void * ) &ulOfferedIPAddress, sizeof( ulOfferedIPAddress ) );\r
-\r
-       /* Copy in the address of the DHCP server being used. */\r
-       memcpy( ( void * ) &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET + dhcpDHCP_SERVER_IP_ADDRESS_OFFSET ] ), ( void * ) &ulDHCPServerAddress, sizeof( ulDHCPServerAddress ) );\r
-\r
-       iptraceSENDING_DHCP_REQUEST();\r
-       if( FreeRTOS_sendto( xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( xDHCPMessage_t ) + sizeof( ucDHCPRequestOptions ) ), FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) == 0 )\r
-       {\r
-               /* The packet was not successfully queued for sending and must be\r
-               returned to the stack. */\r
-               FreeRTOS_ReleaseUDPPayloadBuffer( pucUDPPayloadBuffer );\r
-       }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-static void prvSendDHCPDiscover( xMACAddress_t *pxMACAddress )\r
-{\r
-uint8_t *pucUDPPayloadBuffer;\r
-struct freertos_sockaddr xAddress;\r
-static const uint8_t ucDHCPDiscoverOptions[] =\r
-{\r
-       /* Do not change the ordering without also changing dhcpCLIENT_IDENTIFIER_OFFSET. */\r
-       dhcpMESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_DISCOVER,                                     /* Message type option. */\r
-       dhcpCLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0,                                         /* Client identifier. */\r
-       dhcpPARAMETER_REQUEST_OPTION_CODE, 3, dhcpSUBNET_MASK_OPTION_CODE, dhcpGATEWAY_OPTION_CODE, hdcpDNS_SERVER_OPTIONS_CODE,        /* Parameter request option. */\r
-       dhcpOPTION_END_BYTE\r
-};\r
-\r
-       pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, pxMACAddress, dhcpREQUEST_OPCODE, ucDHCPDiscoverOptions, sizeof( ucDHCPDiscoverOptions ) );\r
-\r
-       iptraceSENDING_DHCP_DISCOVER();\r
-       if( FreeRTOS_sendto( xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( xDHCPMessage_t ) + sizeof( ucDHCPDiscoverOptions ) ), FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) == 0 )\r
-       {\r
-               /* The packet was not successfully queued for sending and must be\r
-               returned to the stack. */\r
-               FreeRTOS_ReleaseUDPPayloadBuffer( pucUDPPayloadBuffer );\r
-       }\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-#endif /* ipconfigUSE_DHCP != 0 */\r
-\r
-\r