// callback function; stack calls this upon DHCP events void DhcpEventHandler(TCPIP_NET_HANDLE hNet, TCPIP_DHCP_EVENT_TYPE evType, const void* param) { if (evType == DHCP_EVENT_BOUND) { SignalDHCPSuccessful(); } }
/***************************************************************************** Function: void DHCPTask(void) Summary: Performs periodic DHCP tasks for all interfaces. Description: This function performs any periodic tasks requied by the DHCP module, such as sending and receiving messages involved with obtaining and maintaining a lease. Precondition: None Parameters: None Returns: None ***************************************************************************/ void DHCPTask(void) { BYTE i; for(i = 0; i < NETWORK_INTERFACES; i++) { LoadState(i); switch(DHCPClient.smState) { case SM_DHCP_DISABLED: // When the module is disabled, do absolutely nothing break; case SM_DHCP_GET_SOCKET: // Open a socket to send and receive broadcast messages on //DHCPClient.hDHCPSocket = UDPOpen(DHCP_CLIENT_PORT, NULL, DHCP_SERVER_PORT); DHCPClient.hDHCPSocket = UDPOpenEx(0,UDP_OPEN_SERVER,DHCP_CLIENT_PORT, DHCP_SERVER_PORT); if(DHCPClient.hDHCPSocket == INVALID_UDP_SOCKET) break; DHCPClient.smState = SM_DHCP_SEND_DISCOVERY; // No break case SM_DHCP_SEND_DISCOVERY: // Assume default IP Lease time of 60 seconds. // This should be minimum possible to make sure that if the // server did not specify lease time, we try again after this // minimum time. DHCPClient.dwLeaseTime = 60; DHCPClient.validValues.val = 0x00; DHCPClient.flags.bits.bIsBound = FALSE; DHCPClient.flags.bits.bOfferReceived = FALSE; // No point in wasting time transmitting a discovery if we are // unlinked. No one will see it. if(!MACIsLinked()) break; #if defined(WF_CS_IO) && defined(STACK_USE_UART) // Note: Use this debug message out to UART with caution. It can prevent slow down stack // performance and possibly prevent STA from properly receiving DHCP IP. // putrsUART("DHCP Send Discovery...\r\n"); #endif // Ensure transmitter is ready to accept data if(UDPIsPutReady(DHCPClient.hDHCPSocket) < 300u) break; // Toggle the BOOTP Broadcast flag to ensure compatibility with // bad DHCP servers that don't know how to handle broadcast // responses. This results in the next discovery attempt to be // made using the opposite mode. DHCPClient.flags.bits.bUseUnicastMode ^= 1; // Ensure that we transmit to the broadcast IP and MAC addresses // The UDP Socket remembers who it was last talking to memset((void*)&UDPSocketInfo[DHCPClient.hDHCPSocket].remote.remoteNode, 0xFF, sizeof(UDPSocketInfo[0].remote.remoteNode)); // Send the DHCP Discover broadcast _DHCPSend(DHCP_DISCOVER_MESSAGE, FALSE); // Start a timer and begin looking for a response DHCPClient.dwTimer = TickGet(); DHCPClient.smState = SM_DHCP_GET_OFFER; break; case SM_DHCP_GET_OFFER: // Check to see if a packet has arrived if(UDPIsGetReady(DHCPClient.hDHCPSocket) < 250u) { // Go back and transmit a new discovery if we didn't get an offer after 2 seconds if(TickGet() - DHCPClient.dwTimer >= DHCP_TIMEOUT) DHCPClient.smState = SM_DHCP_SEND_DISCOVERY; break; } // Let the DHCP server module know that there is a DHCP server // on this network DHCPClient.flags.bits.bDHCPServerDetected = TRUE; // Check to see if we received an offer if(_DHCPReceive() != DHCP_OFFER_MESSAGE) break; DHCPClient.smState = SM_DHCP_SEND_REQUEST; // No break case SM_DHCP_SEND_REQUEST: if(UDPIsPutReady(DHCPClient.hDHCPSocket) < 258u) break; // Ensure that we transmit to the broadcast IP and MAC addresses // The UDP Socket remembers who it was last talking to, so // we must set this back to the broadcast address since the // current socket values are the unicast addresses of the DHCP // server. memset((void*)&UDPSocketInfo[DHCPClient.hDHCPSocket].remote.remoteNode, 0xFF, sizeof(UDPSocketInfo[0].remote.remoteNode)); // Send the DHCP request message _DHCPSend(DHCP_REQUEST_MESSAGE, FALSE); // Start a timer and begin looking for a response DHCPClient.dwTimer = TickGet(); DHCPClient.smState = SM_DHCP_GET_REQUEST_ACK; break; case SM_DHCP_GET_REQUEST_ACK: // Check to see if a packet has arrived if(UDPIsGetReady(DHCPClient.hDHCPSocket) < 250u) { // Go back and transmit a new discovery if we didn't get an ACK after 2 seconds if(TickGet() - DHCPClient.dwTimer >= DHCP_TIMEOUT) DHCPClient.smState = SM_DHCP_SEND_DISCOVERY; break; } // Check to see if we received an offer switch(_DHCPReceive()) { case DHCP_ACK_MESSAGE: UDPClose(DHCPClient.hDHCPSocket); DHCPClient.hDHCPSocket = INVALID_UDP_SOCKET; DHCPClient.dwTimer = TickGet(); DHCPClient.smState = SM_DHCP_BOUND; DHCPClient.flags.bits.bEvent = 1; DHCPClient.flags.bits.bIsBound = TRUE; if(DHCPClient.validValues.bits.IPAddress) { AppConfig.MyIPAddr = DHCPClient.tempIPAddress; #if defined(WF_CS_IO) #if defined(STACK_USE_UART ) putrsUART("DHCP client successful\r\n"); #endif SignalDHCPSuccessful(); #endif } if(DHCPClient.validValues.bits.Mask) AppConfig.MyMask = DHCPClient.tempMask; if(DHCPClient.validValues.bits.Gateway) AppConfig.MyGateway = DHCPClient.tempGateway; #if defined(STACK_USE_DNS) if(DHCPClient.validValues.bits.DNS) AppConfig.PrimaryDNSServer.Val = DHCPClient.tempDNS.Val; AppConfig.SecondaryDNSServer.Val = 0x00000000ul; if(DHCPClient.validValues.bits.DNS2) AppConfig.SecondaryDNSServer.Val = DHCPClient.tempDNS2.Val; #endif //if(DHCPClient.validValues.bits.HostName) // memcpy(AppConfig.NetBIOSName, (void*)DHCPClient.tempHostName, sizeof(AppConfig.NetBIOSName)); break; case DHCP_NAK_MESSAGE: DHCPClient.smState = SM_DHCP_SEND_DISCOVERY; break; } break; case SM_DHCP_BOUND: if(TickGet() - DHCPClient.dwTimer < TICK_SECOND) break; // Check to see if our lease is still valid, if so, decrement lease // time if(DHCPClient.dwLeaseTime >= 2ul) { DHCPClient.dwTimer += TICK_SECOND; DHCPClient.dwLeaseTime--; break; } // Open a socket to send and receive DHCP messages on //DHCPClient.hDHCPSocket = UDPOpen(DHCP_CLIENT_PORT, NULL, DHCP_SERVER_PORT); DHCPClient.hDHCPSocket = UDPOpenEx(0,UDP_OPEN_SERVER,DHCP_CLIENT_PORT, DHCP_SERVER_PORT); if(DHCPClient.hDHCPSocket == INVALID_UDP_SOCKET) break; DHCPClient.smState = SM_DHCP_SEND_RENEW; // No break case SM_DHCP_SEND_RENEW: case SM_DHCP_SEND_RENEW2: case SM_DHCP_SEND_RENEW3: if(UDPIsPutReady(DHCPClient.hDHCPSocket) < 258u) break; // Send the DHCP request message _DHCPSend(DHCP_REQUEST_MESSAGE, TRUE); DHCPClient.flags.bits.bOfferReceived = FALSE; // Start a timer and begin looking for a response DHCPClient.dwTimer = TickGet(); DHCPClient.smState++; break; case SM_DHCP_GET_RENEW_ACK: case SM_DHCP_GET_RENEW_ACK2: case SM_DHCP_GET_RENEW_ACK3: // Check to see if a packet has arrived if(UDPIsGetReady(DHCPClient.hDHCPSocket) < 250u) { // Go back and transmit a new discovery if we didn't get an ACK after 2 seconds if(TickGet() - DHCPClient.dwTimer >= DHCP_TIMEOUT) { if(++DHCPClient.smState > SM_DHCP_GET_RENEW_ACK3) DHCPClient.smState = SM_DHCP_SEND_DISCOVERY; } break; } // Check to see if we received an offer switch(_DHCPReceive()) { case DHCP_ACK_MESSAGE: UDPClose(DHCPClient.hDHCPSocket); DHCPClient.hDHCPSocket = INVALID_UDP_SOCKET; DHCPClient.dwTimer = TickGet(); DHCPClient.smState = SM_DHCP_BOUND; DHCPClient.flags.bits.bEvent = 1; break; case DHCP_NAK_MESSAGE: DHCPClient.smState = SM_DHCP_SEND_DISCOVERY; break; } break; } } }