Example #1
0
/*****************************************************************************
  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);
				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;
	
				// 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].remoteNode, 0xFF, sizeof(UDPSocketInfo[0].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].remoteNode, 0xFF, sizeof(UDPSocketInfo[0].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(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);
				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;
		}
	}
}
Example #2
0
/*****************************************************************************
  Function:
	void DHCPTask(void)

  Summary:
	Performs periodic DHCP tasks.

  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)
{
    static TICK eventTime;

    switch(smDHCPState)
    {
		case SM_DHCP_GET_SOCKET:
			// Open a socket to send and receive broadcast messages on
	        DHCPSocket = UDPOpen(DHCP_CLIENT_PORT, NULL, DHCP_SERVER_PORT);
			if(DHCPSocket == INVALID_UDP_SOCKET)
				break;

			smDHCPState = SM_DHCP_SEND_DISCOVERY;
			// No break

		case SM_DHCP_SEND_DISCOVERY:
			if(UDPIsPutReady(DHCPSocket) < 300u)
				break;

			// Ensure that we transmit to the broadcast IP and MAC addresses
			// The UDP Socket remembers who it was last talking to
			memset((void*)&UDPSocketInfo[DHCPSocket].remoteNode, 0xFF, sizeof(UDPSocketInfo[DHCPSocket].remoteNode));

		    // Assume default IP Lease time of 60 seconds.
		    // This should be minimum possible to make sure that if
		    // server did not specify lease time, we try again after this minimum time.
		    DHCPLeaseTime.Val = 60;
			ValidValues.Val = 0x00;
			DHCPBindCount = 0;
			DHCPFlags.bits.bIsBound = FALSE;	
			DHCPFlags.bits.bOfferReceived = FALSE;
			
			// Send the DHCP Discover broadcast
			_DHCPSend(DHCP_DISCOVER_MESSAGE, FALSE);
			
			// Start a timer and begin looking for a response
			eventTime = TickGet();
			smDHCPState = SM_DHCP_GET_OFFER;
	        break;

		case SM_DHCP_GET_OFFER:
			// Check to see if a packet has arrived
			if(UDPIsGetReady(DHCPSocket) < 250u)
			{
				// Go back and transmit a new discovery if we didn't get an offer after 2 seconds
				if(TickGet() - eventTime >= DHCP_TIMEOUT)
					smDHCPState = SM_DHCP_SEND_DISCOVERY;
				break;
			}

			// Let the DHCP server module know that there is a DHCP server 
			// on this network
			DHCPFlags.bits.bDHCPServerDetected = TRUE;

			// Check to see if we received an offer
			if(_DHCPReceive() != DHCP_OFFER_MESSAGE)
				break;

			smDHCPState = SM_DHCP_SEND_REQUEST;
			// No break

		case SM_DHCP_SEND_REQUEST:
			if(UDPIsPutReady(DHCPSocket) < 258u)
				break;

			// Send the DHCP request message
			_DHCPSend(DHCP_REQUEST_MESSAGE, FALSE);
			
			// Start a timer and begin looking for a response
			eventTime = TickGet();
			smDHCPState = SM_DHCP_GET_REQUEST_ACK;
	        break;

		case SM_DHCP_GET_REQUEST_ACK:
			// Check to see if a packet has arrived
			if(UDPIsGetReady(DHCPSocket) < 250u)
			{
				// Go back and transmit a new discovery if we didn't get an ACK after 2 seconds
				if(TickGet() - eventTime >= DHCP_TIMEOUT)
					smDHCPState = SM_DHCP_SEND_DISCOVERY;
				break;
			}

			// Check to see if we received an offer
			switch(_DHCPReceive())
			{
				case DHCP_ACK_MESSAGE:
					UDPClose(DHCPSocket);
					DHCPSocket = INVALID_UDP_SOCKET;
					eventTime = TickGet();
					smDHCPState = SM_DHCP_BOUND;

	                DHCPFlags.bits.bIsBound = TRUE;	
	                DHCPBindCount++;
					if(ValidValues.bits.IPAddress)
		                AppConfig.MyIPAddr = tempIPAddress;
					if(ValidValues.bits.Mask)
						AppConfig.MyMask = tempMask;
					if(ValidValues.bits.Gateway)
						AppConfig.MyGateway = tempGateway;
					#if defined(STACK_USE_DNS)
						if(ValidValues.bits.DNS)
							AppConfig.PrimaryDNSServer = tempDNS;
						AppConfig.SecondaryDNSServer.Val = ValidValues.bits.DNS2 ? tempDNS2.Val : 0x00000000ul;
					#endif
//					if(ValidValues.bits.HostName)
//						memcpy(AppConfig.NetBIOSName, (void*)tempHostName, sizeof(AppConfig.NetBIOSName));

					break;

				case DHCP_NAK_MESSAGE:
					smDHCPState = SM_DHCP_SEND_DISCOVERY;
					break;
			}
			break;

		case SM_DHCP_BOUND:
	        if(TickGet() - eventTime < TICK_SECOND)
				break;

			// Check to see if our lease is still valid, if so, decrement lease 
			// time
			if(DHCPLeaseTime.Val >= 2ul)
			{
				eventTime += TICK_SECOND;
				DHCPLeaseTime.Val--;
				break;
			}
			
			// Open a socket to send and receive DHCP messages on
	        DHCPSocket = UDPOpen(DHCP_CLIENT_PORT, NULL, DHCP_SERVER_PORT);
			if(DHCPSocket == INVALID_UDP_SOCKET)
				break;
			
			smDHCPState = SM_DHCP_SEND_RENEW;
			// No break

		case SM_DHCP_SEND_RENEW:
		case SM_DHCP_SEND_RENEW2:
		case SM_DHCP_SEND_RENEW3:
			if(UDPIsPutReady(DHCPSocket) < 258u)
				break;

			// Send the DHCP request message
			_DHCPSend(DHCP_REQUEST_MESSAGE, TRUE);
			DHCPFlags.bits.bOfferReceived = FALSE;
			
			// Start a timer and begin looking for a response
			eventTime = TickGet();
			smDHCPState++;
			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(DHCPSocket) < 250u)
			{
				// Go back and transmit a new discovery if we didn't get an ACK after 2 seconds
				if(TickGet() - eventTime >=  DHCP_TIMEOUT)
				{
					if(++smDHCPState > SM_DHCP_GET_RENEW_ACK3)
						smDHCPState = SM_DHCP_SEND_DISCOVERY;
				}
				break;
			}

			// Check to see if we received an offer
			switch(_DHCPReceive())
			{
				case DHCP_ACK_MESSAGE:
					UDPClose(DHCPSocket);
					DHCPSocket = INVALID_UDP_SOCKET;
					eventTime = TickGet();
					DHCPBindCount++;
					smDHCPState = SM_DHCP_BOUND;
					break;

				case DHCP_NAK_MESSAGE:
					smDHCPState = SM_DHCP_SEND_DISCOVERY;
					break;
			}
			break;

		// Handle SM_DHCP_DISABLED state by doing nothing.  Default case needed 
		// to supress compiler diagnostic.
		default:	
			break;
	}
}
Example #3
0
/*********************************************************************
 * Function:        void DHCPTask(void)
 *
 * PreCondition:    DHCPInit() is already called AND
 *                  IPGetHeader() is called with
 *                  IPFrameType == IP_PROT_UDP
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Fetches pending UDP packet from MAC receive buffer
 *                  and dispatches it appropriate UDP socket.
 *                  If not UDP socket is matched, UDP packet is
 *                  silently discarded.
 *
 * Note:            Caller must make sure that MAC receive buffer
 *                  access pointer is set to begining of UDP packet.
 *                  Required steps before calling this function is:
 *
 *                  If ( MACIsRxReady() )
 *                  {
 *                      MACGetHeader()
 *                      If MACFrameType == IP
 *                          IPGetHeader()
 *                          if ( IPFrameType == IP_PROT_UDP )
 *                              Call DHCPTask()
 *                  ...
 ********************************************************************/
void DHCPTask(void)
{
    NODE_INFO DHCPServerNode;
    static TICK lastTryTick;
    BYTE DHCPRecvReturnValue;

    switch(smDHCPState)
    {
    case SM_DHCP_INIT:
        DHCPServerNode.MACAddr.v[0] = 0xff;
        DHCPServerNode.MACAddr.v[1] = 0xff;
        DHCPServerNode.MACAddr.v[2] = 0xff;
        DHCPServerNode.MACAddr.v[3] = 0xff;
        DHCPServerNode.MACAddr.v[4] = 0xff;
        DHCPServerNode.MACAddr.v[5] = 0xff;
        DHCPServerNode.IPAddr.Val = 0xffffffff;
        tempIPAddress.Val = 0x0;
        DHCPSocket = UDPOpen(DHCP_CLIENT_PORT,
                             &DHCPServerNode,
                             DHCP_SERVER_PORT);
        lastTryTick = TickGet();
        smDHCPState = SM_DHCP_RESET_WAIT;
        /* No break */

    case SM_DHCP_RESET_WAIT:
        if ( TickGetDiff(TickGet(), lastTryTick) >= (TICK_SECOND/(TICK)5) )
            smDHCPState = SM_DHCP_BROADCAST;
        break;

    case SM_DHCP_BROADCAST:
        /*
         * If we have already obtained some IP address, renew it.
         */
        if ( tempIPAddress.Val != 0x00000 )
        {
            smDHCPState = SM_DHCP_REQUEST;
        }
        else if ( UDPIsPutReady(DHCPSocket) )
        {
            /*
             * To minimize code requirement, user must make sure that
             * above call will be successful by making at least one
             * UDP socket available.
             * Usually this will be the case, given that DHCP will be
             * the first one to use UDP socket.
             *
             * Also, we will not check for transmitter readiness,
             * we assume it to be ready.
             */

            _DHCPSend(DHCP_DISCOVER_MESSAGE);

            // DEBUG
            USARTPut('\n');
            USARTPut('\r');
            USARTPut('D');

            lastTryTick = TickGet();
            smDHCPState = SM_DHCP_DISCOVER;
        }

        break;


    case SM_DHCP_DISCOVER:
        if ( TickGetDiff(TickGet(), lastTryTick) >= DHCP_TIMEOUT )
        {
            smDHCPState = SM_DHCP_BROADCAST;
            //return;
        }

        if ( UDPIsGetReady(DHCPSocket) )
        {
            // DEBUG
            USARTPut('R');

            if ( _DHCPReceive() == DHCP_OFFER_MESSAGE )
            {
                // DEBUG
                USARTPut('O');

                smDHCPState = SM_DHCP_REQUEST;
            }
            else
                break;
        }
        else
            break;



    case SM_DHCP_REQUEST:
        if ( UDPIsPutReady(DHCPSocket) )
        {
            _DHCPSend(DHCP_REQUEST_MESSAGE);

            lastTryTick = TickGet();
            smDHCPState = SM_DHCP_BIND;
        }
        break;

    case SM_DHCP_BIND:
        if ( UDPIsGetReady(DHCPSocket) )
        {
            DHCPRecvReturnValue = _DHCPReceive();
            if ( DHCPRecvReturnValue == DHCP_NAK_MESSAGE )
            {
               // (RSS) NAK recieved.  DHCP server didn't like our DHCP Request format
                USARTPut('n');
                smDHCPState = SM_DHCP_REQUEST;   // Request again
            }
            else if ( DHCPRecvReturnValue == DHCP_ACK_MESSAGE )
            {
                // DEBUG
                USARTPut('B');

                /*
                 * Once DCHP is successful, release the UDP socket
                 * This will ensure that UDP layer discards any further
                 * DHCP related packets.
                 */
                UDPClose(DHCPSocket);
                DHCPSocket = INVALID_UDP_SOCKET;

                lastTryTick = TickGet();
                smDHCPState = SM_DHCP_BOUND;

                MY_IP_BYTE1     = tempIPAddress.v[0];
                MY_IP_BYTE2     = tempIPAddress.v[1];
                MY_IP_BYTE3     = tempIPAddress.v[2];
                MY_IP_BYTE4     = tempIPAddress.v[3];

                MY_MASK_BYTE1   = tempMask.v[0];
                MY_MASK_BYTE2   = tempMask.v[1];
                MY_MASK_BYTE3   = tempMask.v[2];
                MY_MASK_BYTE4   = tempMask.v[3];

                MY_GATE_BYTE1   = tempGateway.v[0];
                MY_GATE_BYTE2   = tempGateway.v[1];
                MY_GATE_BYTE3   = tempGateway.v[2];
                MY_GATE_BYTE4   = tempGateway.v[3];

                DHCPState.bits.bIsBound = TRUE;

                DHCPBindCount++;

                return;
            }
        }
        else if ( TickGetDiff(TickGet(), lastTryTick) >= DHCP_TIMEOUT )
        {
            USARTPut('t');
            smDHCPState = SM_DHCP_BROADCAST;
        }
        break;

    case SM_DHCP_BOUND:
        /*
         * Keep track of how long we use this IP configuration.
         * When lease period expires, renew the configuration.
         */
        if ( TickGetDiff(TickGet(), lastTryTick) >= TICK_SECOND )
        {
            DHCPLeaseTime.Val -= 1;
            if ( DHCPLeaseTime.Val == 0 )
                smDHCPState = SM_DHCP_INIT;
            lastTryTick = TickGet();
        }
    }

}
Example #4
0
/*********************************************************************
 * Function:        void DHCPTask(void)
 *
 * PreCondition:    DHCPInit() is already called AND
 *                  IPGetHeader() is called with
 *                  IPFrameType == IP_PROT_UDP
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Fetches pending UDP packet from MAC receive buffer
 *                  and dispatches it appropriate UDP socket.
 *                  If not UDP socket is matched, UDP packet is
 *                  silently discarded.
 *
 * Note:            Caller must make sure that MAC receive buffer
 *                  access pointer is set to begining of UDP packet.
 *                  Required steps before calling this function is:
 *
 *                  If ( MACIsRxReady() )
 *                  {
 *                      MACGetHeader()
 *                      If MACFrameType == IP
 *                          IPGetHeader()
 *                          if ( IPFrameType == IP_PROT_UDP )
 *                              Call DHCPTask()
 *                  ...
 ********************************************************************/
void DHCPTask(void)
{
   NODE_INFO DHCPServerNode;
   static TICKTYPE lastTryTick;
   BYTE DHCPRecvReturnValue;
   TICKTYPE tickDiff;
   //static int8 debugLastState;

   //debugLastState = smDHCPState;

    switch(smDHCPState)
    {
   case SM_DHCP_INIT_FIRST_TIME:
        tempIPAddress.Val = 0x0;
//        smDHCPState = SM_DHCP_INIT;         // State automatically changes
        /* No break */

    case SM_DHCP_INIT:
        //debug(debug_putc,"\r\n\r\nDHCP: INIT");

        //dsr add 061404
        //MY_IP=0;

        DHCPServerNode.MACAddr.v[0] = 0xff;
        DHCPServerNode.MACAddr.v[1] = 0xff;
        DHCPServerNode.MACAddr.v[2] = 0xff;
        DHCPServerNode.MACAddr.v[3] = 0xff;
        DHCPServerNode.MACAddr.v[4] = 0xff;
        DHCPServerNode.MACAddr.v[5] = 0xff;
        DHCPServerNode.IPAddr.Val = 0xffffffff;
        DHCPSocket = UDPOpen(DHCP_CLIENT_PORT,
                             &DHCPServerNode,
                             DHCP_SERVER_PORT);
        lastTryTick = TickGet();
        smDHCPState = SM_DHCP_RESET_WAIT;
        /* No break */

    case SM_DHCP_RESET_WAIT:
        if ( TickGetDiff(TickGet(), lastTryTick) >= (TICKS_PER_SECOND/5) )
            //debug(debug_putc,"\r\n\r\nDHCP: RESET_WAIT");
            smDHCPState = SM_DHCP_BROADCAST;
        break;

    case SM_DHCP_BROADCAST:
       // Assume default IP Lease time of 60 seconds.
       // This should be minimum possible to make sure that if
       // server did not specify lease time, we try again after this minimum time.
       DHCPLeaseTime.Val = 60;

        // If we have already obtained some IP address, renew it.
        if(DHCPState.bits.bIsBound)
        {
            smDHCPState = SM_DHCP_REQUEST;
        }
        else if ( UDPIsPutReady(DHCPSocket) )
        {
            // To minimize code requirement, user must make sure that
            // above call will be successful by making at least one
            // UDP socket available.
            // Usually this will be the case, given that DHCP will be
            // the first one to use UDP socket.
            // Also, we will not check for transmitter readiness,
            // we assume it to be ready.
            _DHCPSend(DHCP_DISCOVER_MESSAGE);
         ValidValues.Val = 0x00;

            lastTryTick = TickGet();
            smDHCPState = SM_DHCP_DISCOVER;
        }

        break;


    case SM_DHCP_DISCOVER:
        if ( TickGetDiff(TickGet(), lastTryTick) >= DHCP_TIMEOUT )
      {
            //debug(debug_putc,"\r\n\r\nDHCP: DISCOVER TO BROADCAST");
            smDHCPState = SM_DHCP_BROADCAST;
            //return;
        }

        if ( UDPIsGetReady(DHCPSocket) )
        {

            if ( _DHCPReceive() == DHCP_OFFER_MESSAGE )
            {
                //debug(debug_putc,"\r\n\r\nDHCP: DISCOVER BACK TO REQUEST");
                smDHCPState = SM_DHCP_REQUEST;
            }
            else
               break;
        }
        else
           break;


    case SM_DHCP_REQUEST:
        if ( UDPIsPutReady(DHCPSocket) )
        {
            _DHCPSend(DHCP_REQUEST_MESSAGE);
            lastTryTick = TickGet();
            smDHCPState = SM_DHCP_BIND;
            //debug(debug_putc,"\r\n\r\nDHCP: REQUEST TO BIND");
        }
        break;

    case SM_DHCP_BIND:
        if ( UDPIsGetReady(DHCPSocket) )
        {
            DHCPRecvReturnValue = _DHCPReceive();
            if ( DHCPRecvReturnValue == DHCP_NAK_MESSAGE )
            {
               // (RSS) NAK recieved.  DHCP server didn't like our DHCP Request format
            DHCPReset();                  // Start all over again
            return;
            }
            else if ( DHCPRecvReturnValue == DHCP_ACK_MESSAGE )
            {
                // Once DCHP is successful, release the UDP socket
                // This will ensure that UDP layer discards any further DHCP related packets.
                UDPClose(DHCPSocket);
                DHCPSocket = INVALID_UDP_SOCKET;

                lastTryTick = TickGet();
                smDHCPState = SM_DHCP_BOUND;

            if(ValidValues.bits.IPAddress)
                   AppConfig.MyIPAddr = tempIPAddress;
            if(ValidValues.bits.Mask)
               AppConfig.MyMask = tempMask;
            if(ValidValues.bits.Gateway)
               AppConfig.MyGateway = tempGateway;
         #if STACK_USE_DNS
            if(ValidValues.bits.DNS)
               AppConfig.PrimaryDNSServer = tempDNS;
         #endif
//            if(ValidValues.bits.HostName)
//               memcpy(AppConfig.NetBIOSName, (void*)tempHostName, sizeof(AppConfig.NetBIOSName));

                DHCPState.bits.bIsBound = TRUE;

                DHCPBindCount++;

                return;
            }
        }
        else if ( TickGetDiff(TickGet(), lastTryTick) >= DHCP_TIMEOUT )
            smDHCPState = SM_DHCP_BROADCAST;
        break;

    case SM_DHCP_BOUND:
        // Keep track of how long we use this IP configuration.
        // When lease period expires, renew the configuration.
        tickDiff = TickGetDiff(TickGet(), lastTryTick);

        if(tickDiff >= TICKS_PER_SECOND)
        {
         do
         {
               DHCPLeaseTime.Val--;
            tickDiff -= TICKS_PER_SECOND;
               if(DHCPLeaseTime.Val == 0u)
                  smDHCPState = SM_DHCP_INIT;
         } while(tickDiff >= TICKS_PER_SECOND);
            lastTryTick = TickGet() - tickDiff;
        }
    }

   /*if (debugLastState != smDHCPState)
   {
      debug_dhcp("\r\nDHCP TASK - ", );
      DebugDHCPDisplayState(debugLastState);
      debug_dhcp(" -> ");
      DebugDHCPDisplayState(smDHCPState);
   }*/
}
Example #5
0
/**
 * Fetches pending UDP packet from MAC receive buffer and dispatches it appropriate UDP socket.
 * If not UDP socket is matched, UDP packet is silently discarded.
 * Note:    Caller must make sure that MAC receive buffer
 *          access pointer is set to begining of UDP packet.
 *          Required steps before calling this function is:
 *          
 *          If ( MACIsRxReady() )
 *          {
 *              MACGetHeader()
 *              If MACFrameType == IP
 *                  IPGetHeader()
 *                  if ( IPFrameType == IP_PROT_UDP )
 *                      Call DHCPTask()
 *              ...
 *          }
 *
 * @@preCondition    DHCPInit() is already called AND IPGetHeader() is called with
 *                  IPFrameType == IP_PROT_UDP
 */
void DHCPTask(void)
{
    NODE_INFO DHCPServerNode;
    static TICK16 lastTryTick;
    BYTE DHCPRecvReturnValue;
    static BYTE broadcastCount;

    switch(smDHCPState)
    {
    case SM_DHCP_INIT_FIRST_TIME:
        tempIPAddress.Val = 0x0;
//        smDHCPState = SM_DHCP_INIT;            // State automatically changes
        /* No break */

    case SM_DHCP_INIT:
        broadcastCount = 3;
        DHCPServerNode.MACAddr.v[0] = 0xff;
        DHCPServerNode.MACAddr.v[1] = 0xff;
        DHCPServerNode.MACAddr.v[2] = 0xff;
        DHCPServerNode.MACAddr.v[3] = 0xff;
        DHCPServerNode.MACAddr.v[4] = 0xff;
        DHCPServerNode.MACAddr.v[5] = 0xff;
        DHCPServerNode.IPAddr.Val = 0xffffffff;
        DHCPSocket = UDPOpen(DHCP_CLIENT_PORT,
                             &DHCPServerNode,
                             DHCP_SERVER_PORT);

        if( DHCPSocket == INVALID_UDP_SOCKET ) {
            #if (DEBUG_DHCP >= LOG_ERROR)
            debugPutMsg(7); //@mxd:7:Could not open UDP socket
            #endif
            break;
        }
                             
        lastTryTick = TickGet16bit();
        smDHCPState = SM_DHCP_RESET_WAIT;
        /* No break */

    case SM_DHCP_RESET_WAIT:
        //More then 200ms has passed
        if ( TickGetDiff16bit(lastTryTick) >= ((TICK16)TICKS_PER_SECOND / (TICK16)5) )
            smDHCPState = SM_DHCP_BROADCAST;
        break;

    case SM_DHCP_BROADCAST:
        // Assume default IP Lease time of 60 seconds.
        // This should be minimum possible to make sure that if
        // server did not specify lease time, we try again after this minimum time.
        DHCPLeaseTime.Val = 60;

        //After a certian number of tries, give up, and assign a static IP address
        if (broadcastCount-- == 0) {
            //Once DCHP is successful, release the UDP socket
            //This will ensure that UDP layer discards any further DHCP related packets.
            UDPClose(DHCPSocket);
            DHCPSocket = INVALID_UDP_SOCKET;

            smDHCPState = SM_DHCP_BOUND;

            DHCPState.bits.bIsBound = TRUE;
            DHCPBindCount++;
            
            //Disable DHCP. No more attempts will be made to obtain a IP from the DHCP server, except
            //if the cable is unplugged.
            DHCPState.bits.bStaticIP = TRUE;
            
            MY_IP_BYTE1 = MY_STATIC_IP_BYTE1;
            MY_IP_BYTE2 = MY_STATIC_IP_BYTE2;
            MY_IP_BYTE3 = MY_STATIC_IP_BYTE3;
            MY_IP_BYTE4 = MY_STATIC_IP_BYTE4;

            #if (DEBUG_DHCP >= LOG_INFO)
            debugPutMsg(10); //@mxd:10:Maxumum Broadcast tries, assigned static IP address
            #endif
            
            return;
        }

        // If we have already obtained some IP address, renew it.
        if(DHCPState.bits.bIsBound)
        {
            smDHCPState = SM_DHCP_REQUEST;
        }
        else if ( UDPIsPutReady(DHCPSocket) )
        {
            // To minimize code requirement, user must make sure that
            // above call will be successful by making at least one
            // UDP socket available.
            // Usually this will be the case, given that DHCP will be
            // the first one to use UDP socket.
            // Also, we will not check for transmitter readiness,
            // we assume it to be ready.
            _DHCPSend(DHCP_DISCOVER_MESSAGE);
            ValidValues.Val = 0x00;

            // DEBUG
             #if (DEBUG_DHCP >= LOG_INFO)
            debugPutMsg(1); //@mxd:1:Broadcast
            #endif

            lastTryTick = TickGet16bit();
            smDHCPState = SM_DHCP_DISCOVER;
        }
        else {
            // DEBUG
             #if (DEBUG_DHCP >= LOG_INFO)
            debugPutMsg(8); //@mxd:8:Can not Broadcase, UDP Not ready!
            #endif
        }

        break;


    case SM_DHCP_DISCOVER:
        if ( TickGetDiff16bit(lastTryTick) >= DHCP_TIMEOUT)    //Timeout has expired
        {
            smDHCPState = SM_DHCP_BROADCAST;

            // DEBUG
            #if (DEBUG_DHCP >= LOG_INFO)
            debugPutMsg(9); //@mxd:9:Discover time out
            #endif

            break;
        }

        if ( UDPIsGetReady(DHCPSocket) )
        {
            // DEBUG
            #if (DEBUG_DHCP >= LOG_INFO)
            debugPutMsg(2); //@mxd:2:Discover
            #endif

            if ( _DHCPReceive() == DHCP_OFFER_MESSAGE )
            {
                // DEBUG
                #if (DEBUG_DHCP >= LOG_INFO)
                debugPutMsg(3); //@mxd:3:Offer Message
                #endif

                smDHCPState = SM_DHCP_REQUEST;
            }
            else
                break;
        }
        else
            break;



    case SM_DHCP_REQUEST:
        if ( UDPIsPutReady(DHCPSocket) )
        {
            _DHCPSend(DHCP_REQUEST_MESSAGE);

            lastTryTick = TickGet16bit();
            smDHCPState = SM_DHCP_BIND;

            // DEBUG
            #if (DEBUG_DHCP >= LOG_INFO)
            debugPutMsg(12); //@mxd:12:Sending Request
            #endif
        }
        break;

    case SM_DHCP_BIND:
        if ( UDPIsGetReady(DHCPSocket) )
        {
            DHCPRecvReturnValue = _DHCPReceive();
            if ( DHCPRecvReturnValue == DHCP_NAK_MESSAGE )
            {
                   // (RSS) NAK recieved.  DHCP server didn't like our DHCP Request (format wrong/IP address allocated to someone else/outside IP pool)
                #if (DEBUG_DHCP >= LOG_WARN)
                debugPutMsg(4);     //@mxd:4:NAK recieved (RSS). DHCP server didn't like our DHCP Request format
                #endif
                DHCPReset();        // Start all over again
                return;
            }
            else if ( DHCPRecvReturnValue == DHCP_ACK_MESSAGE )
            {
                // DEBUG
                #if (DEBUG_DHCP >= LOG_INFO)
                debugPutMsg(5);     //@mxd:5:ACK Received
                #endif

                // Once DCHP is successful, release the UDP socket
                // This will ensure that UDP layer discards any further DHCP related packets.
                UDPClose(DHCPSocket);
                DHCPSocket = INVALID_UDP_SOCKET;

                lastTryTick = TickGet16bit();
                smDHCPState = SM_DHCP_BOUND;

                if(ValidValues.bits.IPAddress) {
                    MY_IP_BYTE1     = tempIPAddress.v[0];
                    MY_IP_BYTE2     = tempIPAddress.v[1];
                    MY_IP_BYTE3     = tempIPAddress.v[2];
                    MY_IP_BYTE4     = tempIPAddress.v[3];
                }

                if(ValidValues.bits.Mask) {
                    MY_MASK_BYTE1   = tempMask.v[0];
                    MY_MASK_BYTE2   = tempMask.v[1];
                    MY_MASK_BYTE3   = tempMask.v[2];
                    MY_MASK_BYTE4   = tempMask.v[3];
                }

                if(ValidValues.bits.Gateway) {
                    MY_GATE_BYTE1   = tempGateway.v[0];
                    MY_GATE_BYTE2   = tempGateway.v[1];
                    MY_GATE_BYTE3   = tempGateway.v[2];
                    MY_GATE_BYTE4   = tempGateway.v[3];
                }

#if defined(STACK_USE_DNS)
                if(ValidValues.bits.DNS) {
                    MY_DNS_BYTE1_SET(tempDNS.v[0]);
                    MY_DNS_BYTE2_SET(tempDNS.v[1]);
                    MY_DNS_BYTE3_SET(tempDNS.v[2]);
                    MY_DNS_BYTE4_SET(tempDNS.v[3]);
                }
#endif
//                if(ValidValues.bits.HostName)
//                    memcpy(AppConfig.NetBIOSName, (void*)tempHostName, sizeof(AppConfig.NetBIOSName));

                DHCPState.bits.bIsBound = TRUE;

                DHCPBindCount++;

                return;
            }
        }
        else if ( TickGetDiff16bit(lastTryTick) >= DHCP_TIMEOUT )   //Timeout has expired
        {
            #if (DEBUG_DHCP >= LOG_WARN)
            debugPutMsg(6);     //@mxd:6:Timeout
            #endif
            smDHCPState = SM_DHCP_BROADCAST;
        }
        break;

    case SM_DHCP_BOUND:
        //If a static IP was assigned, it never times out. Only when the cable is unplugged, will
        //the DHCP server be reset, and start looking for an IP again.
        if (DHCPState.bits.bStaticIP) return;
        
        // Keep track of how long we use this IP configuration.
        // When lease period expires, renew the configuration.
        while ( TickGetDiff16bit(lastTryTick) >= ((TICK16)TICKS_PER_SECOND) )
        {
            DHCPLeaseTime.Val--;        //Decrement lease time
            if ( DHCPLeaseTime.Val == 0 ) {
                smDHCPState = SM_DHCP_INIT;

                // DEBUG
                #if (DEBUG_DHCP >= LOG_INFO)
                debugPutMsg(11);     //@mxd:11:Lease time expired
                #endif
            }

            //Add 1 seconds to lastTryTick - will cause this statement to execute in 1 second again
            lastTryTick += ((TICK16)TICKS_PER_SECOND);  //Add 1 second to lastTryTick
        }
    }

}