Ejemplo n.º 1
0
/**
 * This FSM checks for new incoming packets, and routes it to appropriate
 * stack components. It also performs timed operations.
 *
 * This function must be called periodically called
 * to make sure that timely response.
 *
 * @preCondition    StackInit() is already called.
 *
 * side affect:     Stack FSM is executed.
 */
void StackTask(void)
{
    static WORD dataCount;
    
#if defined(STACK_USE_ICMP)
    static BYTE data[MAX_ICMP_DATA_LEN];
    static WORD ICMPId;
    static WORD ICMPSeq;
#endif
    IP_ADDR destIP;     //Is filled with the Destination IP address contained in the IP header
    
    union
    {
        BYTE MACFrameType;
        BYTE IPFrameType;
        ICMP_CODE ICMPCode;
    } type;

    BOOL lbContinue;

    do
    {
        lbContinue = FALSE;

        switch(smStack)
        {
        case SM_STACK_IDLE:
        case SM_STACK_MAC:

            //debugPutGenRomStr(2, (ROM char*)"1");     //@mxd:2:%s

            //Check if the MAC RX Buffer has any data, and if it does, read the header.
            //Get the next header from the NIC. The node who sent it's address will be copied to 
            //'remoteNode.MACAddr'.
            //Header was NOT read if MACGetHeader returned FALSE
            if ( !MACGetHeader(&remoteNode.MACAddr, &type.MACFrameType) )
            {
                //debugPutGenRomStr(2, (ROM char*)"2");     //@mxd:2:%s
                
                //MODIFIED DHCP BEGIN
                // ADDED
	            #if defined(STACK_USE_DHCP)
	            // Normally, an application would not include  DHCP module
	            // if it is not enabled. But in case some one wants to disable
	            // DHCP module at run-time, remember to not clear our IP
	            // address if link is removed.
	            if(STACK_IS_DHCP_ENABLED)
	            {
		            if(!MACIsLinked())
		            {
	                    AppConfig.MyIPAddr.v[0] = MY_DEFAULT_IP_ADDR_BYTE1;
                        AppConfig.MyIPAddr.v[1] = MY_DEFAULT_IP_ADDR_BYTE2;
                        AppConfig.MyIPAddr.v[2] = MY_DEFAULT_IP_ADDR_BYTE3;
                        AppConfig.MyIPAddr.v[3] = MY_DEFAULT_IP_ADDR_BYTE4;

                        AppConfig.MyMask.v[0] = MY_DEFAULT_MASK_BYTE1;
                        AppConfig.MyMask.v[1] = MY_DEFAULT_MASK_BYTE2;
                        AppConfig.MyMask.v[2] = MY_DEFAULT_MASK_BYTE3;
                        AppConfig.MyMask.v[3] = MY_DEFAULT_MASK_BYTE4;
    
			            DHCPFlags.bits.bDHCPServerDetected = FALSE;

                        stackFlags.bits.bInConfigMode = TRUE;

			            DHCPReset();
		            }
	
		            // DHCP must be called all the time even after IP configuration is
		            // discovered.
		            // DHCP has to account lease expiration time and renew the configuration
		            // time.
		            DHCPTask();
		
		            if(DHCPIsBound())
			            stackFlags.bits.bInConfigMode = FALSE;
	            }
	            #endif
                //MODIFIED DHCP END


                //MODIFIED DHCP BEGIN
                // Removed
                /*
                #if defined(STACK_USE_DHCP)
                    // Normally, an application would not include DHCP module
                    // if it is not enabled. But in case some one wants to disable
                    // DHCP module at run-time, remember to not clear our IP
                    // address if link is removed.
                    //Set our IP to 0.0.0.0 if all the following are TRUE:
                    // - DHCP is enabled
                    // - MAC is not linked yet (or cable is unplugged)
                    if (STACK_IS_DHCP_ENABLED)
                    {
                        if ( !MACIsLinked() )
                        {
                            //debugPutGenRomStr(2, (ROM char*)"3");     //@mxd:2:%s

                            #if (DEBUG_STACKTSK >= LOG_INFO)
                            //debugPutMsg(1); //@mxd:1:DHCP Enabled but MAC not linked yet - set IP to 0.0.0.0
                            #endif
                            
                            //if (stackFlags.bits.bInConfigMode) {
                                //IP address must be 0.0.0.0 before DHCP has obtained a valid IP address
                                MY_IP_BYTE1 = 0;
                                MY_IP_BYTE2 = 0;
                                MY_IP_BYTE3 = 0;
                                MY_IP_BYTE4 = 0;
                            //}

                            stackFlags.bits.bInConfigMode = TRUE;
                            DHCPReset();
                        }
                    }
                #endif
                */
                //MODIFIED DHCP END

                break;      //case SM_STACK_IDLE:  AND   case SM_STACK_MAC:
            }

            //debugPutGenRomStr(2, (ROM char*)"4");     //@mxd:2:%s

            lbContinue = TRUE;
            if ( type.MACFrameType == MAC_IP ) {
                smStack = SM_STACK_IP;
                #if (DEBUG_STACKTSK >= LOG_DEBUG)
                debugPutMsg(2); //@mxd:2:Reading MAC IP header
                #endif
            }
            else if ( type.MACFrameType == MAC_ARP ) {
                smStack = SM_STACK_ARP;
                #if (DEBUG_STACKTSK >= LOG_DEBUG)
                debugPutMsg(3); //@mxd:3:Reading MAC ARP header
                #endif
            }
            else {
                MACDiscardRx(); //Discard the contents of the current RX buffer
                #if (DEBUG_STACKTSK >= LOG_WARN)
                debugPutMsg(4); //@mxd:4:Unknown MAC header read, MAC Frame Type = 0x%x
                debugPutByteHex(type.MACFrameType);
                #endif
            }
            break;      //case SM_STACK_IDLE:  AND   case SM_STACK_MAC:

        case SM_STACK_ARP:
            if ( ARPProcess() )
                smStack = SM_STACK_IDLE;
            //lbContinue = FALSE;   //Removed in latest Microchip TCP/IP stack
            break;

        case SM_STACK_IP:
            if ( IPGetHeader(&destIP,  /* Get Destination IP Address as received in IP header */
                             &remoteNode,
                             &type.IPFrameType,
                             &dataCount) )
            {
                lbContinue = TRUE;
                if ( type.IPFrameType == IP_PROT_ICMP )
                {
                    smStack = SM_STACK_ICMP;

#if defined(STACK_USE_IP_GLEANING)
                    if(stackFlags.bits.bInConfigMode && STACK_IS_DHCP_ENABLED)
                    {
                        // Accoriding to "IP Gleaning" procedure,
                        // when we receive an ICMP packet with a valid
                        // IP address while we are still in configuration
                        // mode, accept that address as ours and conclude
                        // configuration mode.
                        if ( destIP.Val != 0xffffffff )
                        {
                            stackFlags.bits.bInConfigMode    = FALSE;
                            MY_IP_BYTE1                 = destIP.v[0];
                            MY_IP_BYTE2                 = destIP.v[1];
                            MY_IP_BYTE3                 = destIP.v[2];
                            MY_IP_BYTE4                 = destIP.v[3];
                            myDHCPBindCount--;
                        }
                    }
#endif
                }

#if defined(STACK_USE_TCP)
                else if ( type.IPFrameType == IP_PROT_TCP )
                    smStack = SM_STACK_TCP;
#endif

#if defined(STACK_USE_UDP)
                else if ( type.IPFrameType == IP_PROT_UDP )
                    smStack = SM_STACK_UDP;
#endif

                else    // Unknown/unsupported higher level protocol
                {
                    lbContinue = FALSE;
                    MACDiscardRx(); //Discard the contents of the current RX buffer

                    smStack = SM_STACK_IDLE;
                }
            }
            else    // Improper IP header version or checksum
            {
                MACDiscardRx(); //Discard the contents of the current RX buffer
                smStack = SM_STACK_IDLE;
            }
            break;      //case SM_STACK_IP:

#if defined(STACK_USE_UDP)
        case SM_STACK_UDP:
            if ( UDPProcess(&remoteNode, &destIP, dataCount) )
                smStack = SM_STACK_IDLE;
            //lbContinue = FALSE;   //Removed in latest Microchip TCP/IP stack
            break;      //case SM_STACK_UDP:
#endif

#if defined(STACK_USE_TCP)
        case SM_STACK_TCP:
            if ( TCPProcess(&remoteNode, &destIP, dataCount) )  //Will return TRUE if TCPProcess finished it's task, else FALSE
                smStack = SM_STACK_IDLE;
            //lbContinue = FALSE;   //Removed in latest Microchip TCP/IP stack
            break;      //case SM_STACK_TCP:
#endif

        case SM_STACK_ICMP:
            smStack = SM_STACK_IDLE;

#if defined(STACK_USE_ICMP)
            if ( dataCount <= (MAX_ICMP_DATA_LEN+9) )
            {
                if ( ICMPGet(&type.ICMPCode,
                             data,
                             (BYTE*)&dataCount,
                             &ICMPId,
                             &ICMPSeq) )
                {
                    if ( type.ICMPCode == ICMP_ECHO_REQUEST )
                    {
                        lbContinue = TRUE;
                        smStack = SM_STACK_ICMP_REPLY;
                    }
                }
            }
#endif
            MACDiscardRx(); //Discard the contents of the current RX buffer
            break;          //case SM_STACK_ICMP:

#if defined(STACK_USE_ICMP)
        case SM_STACK_ICMP_REPLY:
            if ( ICMPIsTxReady() )
            {
                ICMPPut(&remoteNode,
                        ICMP_ECHO_REPLY,
                        data,
                        (BYTE)dataCount,
                        ICMPId,
                        ICMPSeq);

                smStack = SM_STACK_IDLE;
            }
            break;          //case SM_STACK_ICMP_REPLY:
#endif

        }       //switch(smStack)

        FAST_USER_PROCESS();
    } while(lbContinue);

#if defined(STACK_USE_TCP)
    // Perform timed TCP FSM.
    TCPTick();
#endif


//MODIFIED DHCP BEGIN
// Removed this
//#if defined(STACK_USE_DHCP)
    /*
     * DHCP must be called all the time even after IP configuration is
     * discovered.
     * DHCP has to account lease expiration time and renew the configuration
     * time.
     */
//    DHCPTask();

//    if(DHCPIsBound())
//        stackFlags.bits.bInConfigMode = FALSE;

//#endif

    //debugPutGenRomStr(2, (ROM char*)"MACTask");     //@mxd:2:%s

    //Perform routine MAC tasks
    MACTask();
}
Ejemplo n.º 2
0
void HTTPExecCmd(BYTE** argv, BYTE argc)
{
    BYTE command;
    BYTE var;
#if defined(ENABLE_REMOTE_CONFIG)
	DWORD_VAL dwVal;
    BYTE CurrentArg;
    WORD_VAL TmpWord;
#endif
    /*
     * Design your pages such that they contain command code
     * as a one character numerical value.
     * Being a one character numerical value greatly simplifies
     * the job.
     */
    command = argv[0][0] - '0';

    /*
     * Find out the cgi file name and interpret parameters
     * accordingly
     */
    switch(command)
    {
    case CGI_CMD_DIGOUT:	// ACTION=0
        /*
         * Identify the parameters.
         * Compare it in upper case format.
         */
        var = argv[1][0] - '0';

        switch(var)
        {
        case CMD_LED1:	// NAME=0
            // Toggle LED.
            LED1_IO ^= 1;
            break;

        case CMD_LED2:	// NAME=1
            // Toggle LED.
            LED2_IO ^= 1;
            break;
         }

         memcpypgm2ram((void*)argv[0], (ROM void*)COMMANDS_OK_PAGE, COMMANDS_OK_PAGE_LEN);
         break;
#if defined(USE_LCD)
    case CGI_CMD_LCDOUT:	// ACTION=1
		if(argc > 2u)	// Text provided in argv[2]
		{
			// Convert %20 to spaces, and other URL transformations
			UnencodeURL(argv[2]);

			// Write 32 received characters or less to LCDText
			if(strlen((char*)argv[2]) < 32u)
			{
				memset(LCDText, ' ', 32);
				strcpy((char*)LCDText, (char*)argv[2]);
			}
			else
			{
				memcpy(LCDText, (void*)argv[2], 32);
			}

			// Write LCDText to the LCD
			LCDUpdate();
		}
		else			// No text provided
		{
			LCDErase();
		}
		memcpypgm2ram((void*)argv[0], (ROM void*)COMMANDS_OK_PAGE, COMMANDS_OK_PAGE_LEN);
        break;
#endif
#if defined(ENABLE_REMOTE_CONFIG)
// Possibly useful code for remotely reconfiguring the board through 
// HTTP
	case CGI_CMD_RECONFIG:	// ACTION=2
		// Loop through all variables that we've been given
		CurrentArg = 1;
		while(argc > CurrentArg)
		{
			// Get the variable identifier (HTML "name"), and 
			// increment to the variable's value
			TmpWord.v[1] = argv[CurrentArg][0];
			TmpWord.v[0] = argv[CurrentArg++][1];
	        var = hexatob(TmpWord);
	        
	        // Make sure the variable's value exists
	        if(CurrentArg >= argc)
	        	break;
	        
	        // Take action with this variable/value
	        switch(var)
	        {
	        case VAR_IP_ADDRESS:
	        case VAR_SUBNET_MASK:
	        case VAR_GATEWAY_ADDRESS:
	        	{
		        	// Convert the returned value to the 4 octect 
		        	// binary representation
			        if(!StringToIPAddress(argv[CurrentArg], (IP_ADDR*)&dwVal))
			        	break;

					// Reconfigure the App to use the new values
			        if(var == VAR_IP_ADDRESS)
			        {
				        // Cause the IP address to be rebroadcast
				        // through Announce.c or the RS232 port since
				        // we now have a new IP address
				        if(dwVal.Val != *(DWORD*)&AppConfig.MyIPAddr)
					        DHCPBindCount++;
					    
					    // Set the new address
			        	memcpy((void*)&AppConfig.MyIPAddr, (void*)&dwVal, sizeof(AppConfig.MyIPAddr));
			        }
			        else if(var == VAR_SUBNET_MASK)
			        	memcpy((void*)&AppConfig.MyMask, (void*)&dwVal, sizeof(AppConfig.MyMask));
			        else if(var == VAR_GATEWAY_ADDRESS)
			        	memcpy((void*)&AppConfig.MyGateway, (void*)&dwVal, sizeof(AppConfig.MyGateway));
		        }
	            break;
	
	        case VAR_DHCP:
	        	if(AppConfig.Flags.bIsDHCPEnabled)
	        	{
		        	if(!(argv[CurrentArg][0]-'0'))
		        	{
		        		AppConfig.Flags.bIsDHCPEnabled = FALSE;
		        	}
		        }
		        else
	        	{
		        	if(argv[CurrentArg][0]-'0')
		        	{
						AppConfig.MyIPAddr.Val = 0x00000000ul;
		        		AppConfig.Flags.bIsDHCPEnabled = TRUE;
				        AppConfig.Flags.bInConfigMode = TRUE;
			        	DHCPReset();
		        	}
		        }
	            break;
	    	}

			// Advance to the next variable (if present)
			CurrentArg++;	
        }
		
		// Save any changes to non-volatile memory
      	SaveAppConfig();


		// Return the same CONFIG.CGI file as a result.
        memcpypgm2ram((void*)argv[0],
             (ROM void*)CONFIG_UPDATE_PAGE, CONFIG_UPDATE_PAGE_LEN);
		break;
#endif

    default:
		memcpypgm2ram((void*)argv[0], (ROM void*)COMMANDS_OK_PAGE, COMMANDS_OK_PAGE_LEN);
        break;
    }

}
Ejemplo n.º 3
0
/******************************************************************************
 * Function:        void StackTask(void)
 * PreCondition:    StackInit() is already called.
 * Input:           None
 * Output:          Stack FSM is executed.
 * Side Effects:    None
 * Note:            This FSM checks for new incoming packets,
 *                  and routes it to appropriate stack components.
 *                  It also performs timed operations.
 *                  This function must be called periodically to
 *                  ensure timely responses.
 ******************************************************************************/
void StackTask(void)
{
    static WORD dataCount;
    IP_ADDR tempLocalIP;
    BOOL lbContinue;

#if defined(STACK_USE_ICMP)
    static BYTE data[MAX_ICMP_DATA_LEN];
    static WORD ICMPId, ICMPSeq;
#endif

    union
    {
        BYTE MACFrameType;
        BYTE IPFrameType;
        ICMP_CODE ICMPCode;
    } type;

    do
    {
        lbContinue = FALSE;

        switch(smStack)
        {
        case SM_STACK_IDLE:
        case SM_STACK_MAC:

            if ( !MACGetHeader(&remoteNode.MACAddr, &type.MACFrameType) )
            {
                #if defined(STACK_USE_DHCP)
                    // Normally, an application would not include  DHCP module
                    // if it is not enabled. But in case some one wants to disable
                    // DHCP module at run-time, remember to not clear our IP
                    // address if link is removed.
                    if ( AppConfig.Flags.bIsDHCPEnabled )
                    {
                        if ( !MACIsLinked() )
                        {
                            AppConfig.MyIPAddr.Val = 0x00000000ul;
                            AppConfig.Flags.bInConfigMode = TRUE;
                            DHCPReset();
                        }
                    }
                #endif

                break;
            }

            lbContinue = TRUE;

            if ( type.MACFrameType == MAC_IP )
                smStack = SM_STACK_IP;
            else if ( type.MACFrameType == MAC_ARP )
                smStack = SM_STACK_ARP;
            else
                MACDiscardRx();
            break;

        case SM_STACK_ARP:
            if ( ARPProcess() )
                smStack = SM_STACK_IDLE;
            break;

        case SM_STACK_IP:
            if ( IPGetHeader(&tempLocalIP,&remoteNode,&type.IPFrameType,&dataCount) )
            {
                lbContinue = TRUE;
                if ( type.IPFrameType == IP_PROT_ICMP )
                {
                    smStack = SM_STACK_ICMP;

#if defined(STACK_USE_IP_GLEANING)
                    if(AppConfig.Flags.bInConfigMode && AppConfig.Flags.bIsDHCPEnabled)
                    {
                        /*
                         * Accoriding to "IP Gleaning" procedure,
                         * when we receive an ICMP packet with a valid
                         * IP address while we are still in configuration
                         * mode, accept that address as ours and conclude
                         * configuration mode.
                         */
                        if( tempLocalIP.Val != 0xffffffff )
                        {
                            AppConfig.Flags.bInConfigMode = FALSE;
                            AppConfig.MyIPAddr = tempLocalIP;
                            myDHCPBindCount--;
                        }
                    }
#endif
                }

#if defined(STACK_USE_TCP)
                else if ( type.IPFrameType == IP_PROT_TCP )
                    smStack = SM_STACK_TCP;
#endif

#if defined(STACK_USE_UDP)
                else if ( type.IPFrameType == IP_PROT_UDP )
                    smStack = SM_STACK_UDP;
#endif

                else    // Unknown/unsupported higher level protocol
                {
                    lbContinue = FALSE;
                    MACDiscardRx();
                    smStack = SM_STACK_IDLE;
                }
            }
            else    // Improper IP header version or checksum
            {
                MACDiscardRx();
                smStack = SM_STACK_IDLE;
            }
            break;

#if defined(STACK_USE_UDP)
        case SM_STACK_UDP:
            if ( UDPProcess(&remoteNode, &tempLocalIP, dataCount) )
                smStack = SM_STACK_IDLE;
            break;
#endif

#if defined(STACK_USE_TCP)
        case SM_STACK_TCP:
            if ( TCPProcess(&remoteNode, &tempLocalIP, dataCount) )
                smStack = SM_STACK_IDLE;
            break;
#endif

        case SM_STACK_ICMP:
            smStack = SM_STACK_IDLE;

#if defined(STACK_USE_ICMP)
            if ( dataCount <= (MAX_ICMP_DATA_LEN+8) )
            {
                if ( ICMPGet(&type.ICMPCode,data,(BYTE*)&dataCount,&ICMPId,&ICMPSeq) )
                {
                    if ( type.ICMPCode == ICMP_ECHO_REQUEST )
                    {
                        lbContinue = TRUE;
                        smStack = SM_STACK_ICMP_REPLY;
                    }
                }
            }
#endif
            MACDiscardRx();
            break;

#if defined(STACK_USE_ICMP)
        case SM_STACK_ICMP_REPLY:
            if ( ICMPIsTxReady() )
            {
                ICMPPut(&remoteNode,ICMP_ECHO_REPLY,data,(BYTE)dataCount,ICMPId,ICMPSeq);
                smStack = SM_STACK_IDLE;
            }
            break;
#endif
        }

    } while(lbContinue);

#if defined(STACK_USE_TCP)
    TCPTick();                 // Perform timed TCP FSM.
#endif

#if defined(STACK_USE_DHCP)
    /*
     * DHCP must be called all the time even after IP configuration is
     * discovered.
     * DHCP has to account lease expiration time and renew the configuration
     * time.
     */
    DHCPTask();

    if(DHCPIsBound()) AppConfig.Flags.bInConfigMode = FALSE;
#endif

#if defined(STACK_USE_SNTP)
    SNTPTask();              // Execute SNTP client FSM
#endif

#if defined(STACK_USE_NBNS)
    NBNSTask();              // Execute NetBIOS name service task
#endif
}
Ejemplo n.º 4
0
/**
 * This FSM checks for new incoming packets, and routes it to appropriate
 * stack components. It also performs timed operations.
 *
 * This function must be called periodically called
 * to make sure that timely response.
 *
 * @preCondition    StackInit() is already called.
 *
 * side affect:     Stack FSM is executed.
 */
void StackTask(void)
{
    static NODE_INFO remoteNode;
    static WORD dataCount;

#if defined(STACK_USE_ICMP)
    static BYTE data[MAX_ICMP_DATA_LEN];
    static WORD ICMPId;
    static WORD ICMPSeq;
#endif
    IP_ADDR destIP;     //Is filled with the Destination IP address contained in the IP header


    union
    {
        BYTE MACFrameType;
        BYTE IPFrameType;
        ICMP_CODE ICMPCode;
    } type;


    BOOL lbContinue;


    lbContinue = TRUE;
    while( lbContinue )
    {
        lbContinue = FALSE;

        switch(smStack)
        {
        case SM_STACK_IDLE:
        case SM_STACK_MAC:

            //Check if the MAC RX Buffer has any data, and if it does, read the header.
            //Get the next header from the NIC. The node who sent it's address will be copied to 
            //'remoteNode.MACAddr'.
            if ( !MACRxbufGetHdr(&remoteNode.MACAddr, &type.MACFrameType) )
            {
                //Header was NOT read if MACRxbufGetHdr returned FALSE

                #if defined(STACK_USE_DHCP)
                    //If DHCP is enabled AND MAC is not linked yet, set our IP to 0
                    if (STACK_IS_DHCP_ENABLED)
                    {
                        if ( !MACIsLinked() )
                        {
                            #if (DEBUG_STACKTSK >= LOG_INFO)
                            debugPutMsg(1); //@mxd:1:DHCP Enabled but MAC not linked yet - set IP to 0.0.0.0
                            #endif
                            
                            //IP address must be 0.0.0.0 before DHCP has obtained a valid IP address
                            MY_IP_BYTE1 = 0;
                            MY_IP_BYTE2 = 0;
                            MY_IP_BYTE3 = 0;
                            MY_IP_BYTE4 = 0;

                            stackFlags.bits.bInConfigMode = TRUE;
                            DHCPReset();
                        }
                    }
                #endif

                break;
            }

            lbContinue = TRUE;
            if ( type.MACFrameType == MAC_IP ) {
                smStack = SM_STACK_IP;
                #if (DEBUG_STACKTSK >= LOG_DEBUG)
                debugPutMsg(2); //@mxd:2:Reading MAC IP header
                #endif
            }
            else if ( type.MACFrameType == MAC_ARP ) {
                smStack = SM_STACK_ARP;
                #if (DEBUG_STACKTSK >= LOG_DEBUG)
                debugPutMsg(3); //@mxd:3:Reading MAC ARP header
                #endif
            }
            else {
                MACRxbufDiscard();
                #if (DEBUG_STACKTSK >= LOG_WARN)
                debugPutMsg(4); //@mxd:4:Unknown MAC header read, MAC Frame Type = 0x%x
                debugPutByteHex(type.MACFrameType);
                #endif
            }
            break;

        case SM_STACK_ARP:
            lbContinue = FALSE;
            if ( ARPProcess() )
                smStack = SM_STACK_IDLE;
            break;

        case SM_STACK_IP:
            if ( IPGetHeader(&destIP,  /* Get Destination IP Address as received in IP header */
                             &remoteNode,
                             &type.IPFrameType,
                             &dataCount) )
            {
                lbContinue = TRUE;
                if ( type.IPFrameType == IP_PROT_ICMP )
                {
                    smStack = SM_STACK_ICMP;

#if defined(STACK_USE_IP_GLEANING)
                    if ( stackFlags.bits.bInConfigMode )
                    {
                        /*
                         * Accoriding to "IP Gleaning" procedure, when we receive an ICMP packet
                         * with a valid IP address while we are still in configuration mode,
                         * accept that address as ours and conclude configuration mode.
                         */
                        if ( destIP.Val != 0xffffffff )
                        {
                            stackFlags.bits.bInConfigMode    = FALSE;
                            MY_IP_BYTE1                 = destIP.v[0];
                            MY_IP_BYTE2                 = destIP.v[1];
                            MY_IP_BYTE3                 = destIP.v[2];
                            MY_IP_BYTE4                 = destIP.v[3];

#if defined(STACK_USE_DHCP)
                            /*
                             * If DHCP and IP gleaning is enabled at the
                             * same time, we must ensuer that once we have
                             * IP address through IP gleaning, we abort
                             * any pending DHCP requests and do not renew
                             * any new DHCP configuration.
                             */
                            DHCPAbort();
#endif
                        }
                    }
#endif
                }

#if defined(STACK_USE_TCP)
                else if ( type.IPFrameType == IP_PROT_TCP )
                    smStack = SM_STACK_TCP;
#endif

#if defined(STACK_USE_UDP)
                else if ( type.IPFrameType == IP_PROT_UDP )
                    smStack = SM_STACK_UDP;
#endif

                else
                {
                    lbContinue = FALSE;
                    MACRxbufDiscard();

                    smStack = SM_STACK_IDLE;
                }
            }
            else
            {
                MACRxbufDiscard();
                smStack = SM_STACK_IDLE;
            }
            break;

#if defined(STACK_USE_UDP)
        case SM_STACK_UDP:
            //tempLocalIP.v[0] = MY_IP_BYTE1;
            //tempLocalIP.v[1] = MY_IP_BYTE2;
            //tempLocalIP.v[2] = MY_IP_BYTE3;
            //tempLocalIP.v[3] = MY_IP_BYTE4;
            if ( UDPProcess(&remoteNode, &destIP, dataCount) )
                smStack = SM_STACK_IDLE;
            lbContinue = FALSE;
            break;
#endif

#if defined(STACK_USE_TCP)
        case SM_STACK_TCP:
            //tempLocalIP.v[0] = MY_IP_BYTE1;
            //tempLocalIP.v[1] = MY_IP_BYTE2;
            //tempLocalIP.v[2] = MY_IP_BYTE3;
            //tempLocalIP.v[3] = MY_IP_BYTE4;
            //Will return TRUE if TCPProcess finished it's task, else FALSE
            if ( TCPProcess(&remoteNode, &destIP, dataCount) )
                smStack = SM_STACK_IDLE;
            lbContinue = FALSE;
            break;
#endif

        case SM_STACK_ICMP:
            smStack = SM_STACK_IDLE;

#if defined(STACK_USE_ICMP)
            if ( dataCount <= (MAX_ICMP_DATA_LEN+9) )
            {
                if ( ICMPGet(&type.ICMPCode,
                             data,
                             (BYTE*)&dataCount,
                             &ICMPId,
                             &ICMPSeq) )
                {
                    if ( type.ICMPCode == ICMP_ECHO_REQUEST )
                    {
                        lbContinue = TRUE;
                        smStack = SM_STACK_ICMP_REPLY;
                    }
                    else
                    {
                        smStack = SM_STACK_IDLE;
                    }
                }
                else
                {
                    smStack = SM_STACK_IDLE;
                }
            }
#endif
            MACRxbufDiscard();
            break;

#if defined(STACK_USE_ICMP)
        case SM_STACK_ICMP_REPLY:
            if ( ICMPIsTxReady() )
            {
                ICMPPut(&remoteNode,
                        ICMP_ECHO_REPLY,
                        data,
                        (BYTE)dataCount,
                        ICMPId,
                        ICMPSeq);

                smStack = SM_STACK_IDLE;
            }
            break;
#endif

        }

    }

#if defined(STACK_USE_TCP)
    // Perform timed TCP FSM.
    TCPTick();
#endif


#if defined(STACK_USE_DHCP)
    /*
     * DHCP must be called all the time even after IP configuration is discovered.
     * DHCP has to account lease expiration time and renew the configuration time.
     */
    DHCPTask();

    if ( DHCPIsBound() )
        stackFlags.bits.bInConfigMode = FALSE;
#endif

    //Perform routine MAC tasks
    MACTask();
}
Ejemplo n.º 5
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);
   }*/
}
Ejemplo n.º 6
0
/*********************************************************************
 * Function:        void StackTask(void)
 *
 * PreCondition:    StackInit() is already called.
 *
 * Input:           None
 *
 * Output:          Stack FSM is executed.
 *
 * Side Effects:    None
 *
 * Note:            This FSM checks for new incoming packets,
 *                  and routes it to appropriate stack components.
 *                  It also performs timed operations.
 *
 *                  This function must be called periodically to
 *                  ensure timely responses.
 *
 ********************************************************************/
void StackTask(void)
{
    WORD dataCount;
    IP_ADDR tempLocalIP;
	BYTE cFrameType;
	BYTE cIPFrameType;


	#if defined(STACK_USE_DHCP_CLIENT)
	// Normally, an application would not include  DHCP module
	// if it is not enabled. But in case some one wants to disable
	// DHCP module at run-time, remember to not clear our IP
	// address if link is removed.
	if(AppConfig.Flags.bIsDHCPEnabled)
	{
		if(!MACIsLinked())
		{
			AppConfig.MyIPAddr.Val = AppConfig.DefaultIPAddr.Val;
			AppConfig.MyMask.Val = AppConfig.DefaultMask.Val;
			DHCPFlags.bits.bDHCPServerDetected = FALSE;
			AppConfig.Flags.bInConfigMode = TRUE;
			DHCPReset();
		}
	
		// DHCP must be called all the time even after IP configuration is
		// discovered.
		// DHCP has to account lease expiration time and renew the configuration
		// time.
		DHCPTask();
		
		if(DHCPIsBound())
			AppConfig.Flags.bInConfigMode = FALSE;
	}
	#endif

	#if defined(STACK_USE_TCP)
	// Perform all TCP time related tasks (retransmit, send acknowledge, close connection, etc)
	TCPTick();
	#endif


	// Process as many incomming packets as we can
	while(MACGetHeader(&remoteNode.MACAddr, &cFrameType))
	{
		switch(cFrameType)
		{
			case MAC_ARP:
				ARPProcess();
				break;
	
			case MAC_IP:
				if(!IPGetHeader(&tempLocalIP, &remoteNode, &cIPFrameType, &dataCount))
					break;

				#if defined(STACK_USE_ICMP_SERVER) || defined(STACK_USE_ICMP_CLIENT)
				if(cIPFrameType == IP_PROT_ICMP)
				{
					ICMPProcess(&remoteNode, dataCount);
					
					#if defined(STACK_USE_IP_GLEANING)
					if(AppConfig.Flags.bInConfigMode && AppConfig.Flags.bIsDHCPEnabled)
					{
						// Accoriding to "IP Gleaning" procedure,
						// when we receive an ICMP packet with a valid
						// IP address while we are still in configuration
						// mode, accept that address as ours and conclude
						// configuration mode.
						if(tempLocalIP.Val != 0xffffffff)
						{
							AppConfig.Flags.bInConfigMode = FALSE;
							AppConfig.MyIPAddr = tempLocalIP;
							myDHCPBindCount--;
						}
					}
					#endif
					break;
				}
				#endif
				
				#if defined(STACK_USE_TCP)
				if(cIPFrameType == IP_PROT_TCP)
				{
					TCPProcess(&remoteNode, &tempLocalIP, dataCount);
					break;
				}
				#endif
				
				#if defined(STACK_USE_UDP)
				if(cIPFrameType == IP_PROT_UDP)
				{
					UDPProcess(&remoteNode, &tempLocalIP, dataCount);
					break;
				}
				#endif

				break;
		}
	}
}
Ejemplo n.º 7
0
/*********************************************************************
 * Function:        void StackTask(void)
 *
 * PreCondition:    StackInit() is already called.
 *
 * Input:           None
 *
 * Output:          Stack FSM is executed.
 *
 * Side Effects:    None
 *
 * Note:            This FSM checks for new incoming packets,
 *                  and routes it to appropriate stack components.
 *                  It also performs timed operations.
 *
 *                  This function must be called periodically to
 *                  ensure timely responses.
 *
 ********************************************************************/
void StackTask(void)
{
    WORD dataCount;
    IP_ADDR tempLocalIP;
    BYTE cFrameType;
    BYTE cIPFrameType;

	#if defined(STACK_USE_DHCP_CLIENT)
	// Normally, an application would not include  DHCP module
	// if it is not enabled. But in case some one wants to disable
	// DHCP module at run-time, remember to not clear our IP
	// address if link is removed.
	if(AppConfig.Flags.bIsDHCPEnabled)
	{
		if(!MACIsLinked())
		{
			AppConfig.MyIPAddr.Val = AppConfig.DefaultIPAddr.Val;
			AppConfig.MyMask.Val = AppConfig.DefaultMask.Val;
			DHCPFlags.bits.bDHCPServerDetected = FALSE;
			AppConfig.Flags.bInConfigMode = TRUE;
			DHCPReset();
		}
	
		// DHCP must be called all the time even after IP configuration is
		// discovered.
		// DHCP has to account lease expiration time and renew the configuration
		// time.
		DHCPTask();
		
		if(DHCPIsBound())
			AppConfig.Flags.bInConfigMode = FALSE;
	}
	#endif

	#if defined(STACK_USE_TCP)
	// Perform all TCP time related tasks (retransmit, send acknowledge, close connection, etc)
	TCPTick();
	#endif


	#if defined(STACK_USE_UDP)
	UDPTask();
	#endif

	// Process as many incomming packets as we can
	while(1)
	{
		//if using the random module, generate entropy
		#if defined(STACK_USE_RANDOM)
			RandomAdd(remoteNode.MACAddr.v[5]);
		#endif

		// We are about to fetch a new packet, make sure that the 
		// UDP module knows that any old RX data it has laying 
		// around will now be gone.
		#if defined(STACK_USE_UDP)
			UDPDiscard();
		#endif

		// Fetch a packet (throws old one away, if not thrown away 
		// yet)
		if(!MACGetHeader(&remoteNode.MACAddr, &cFrameType))
			break;

		// Dispatch the packet to the appropriate handler
		switch(cFrameType)
		{
			case MAC_ARP:
				ARPProcess();
				break;
	
			case MAC_IP:
				if(!IPGetHeader(&tempLocalIP, &remoteNode, &cIPFrameType, &dataCount))
					break;

				#if defined(STACK_USE_ICMP_SERVER) || defined(STACK_USE_ICMP_CLIENT)
				if(cIPFrameType == IP_PROT_ICMP)
				{
					#if defined(STACK_USE_IP_GLEANING)
					if(AppConfig.Flags.bInConfigMode && AppConfig.Flags.bIsDHCPEnabled)
					{
						// Accoriding to "IP Gleaning" procedure,
						// when we receive an ICMP packet with a valid
						// IP address while we are still in configuration
						// mode, accept that address as ours and conclude
						// configuration mode.
						if(tempLocalIP.Val != 0xffffffff)
						{
							AppConfig.Flags.bInConfigMode = FALSE;
							AppConfig.MyIPAddr = tempLocalIP;
							myDHCPBindCount--;
						}
					}
					#endif

					// Process this ICMP packet if it the destination IP address matches our address or one of the broadcast IP addressees
					if( (tempLocalIP.Val == AppConfig.MyIPAddr.Val) ||
						(tempLocalIP.Val == 0xFFFFFFFF) ||
						(tempLocalIP.Val == ((AppConfig.MyIPAddr.Val & AppConfig.MyMask.Val) | ~AppConfig.MyMask.Val)))
					{
						ICMPProcess(&remoteNode, dataCount);
					}

					break;
				}
				#endif
				
				#if defined(STACK_USE_TCP)
				if(cIPFrameType == IP_PROT_TCP)
				{
					TCPProcess(&remoteNode, &tempLocalIP, dataCount);
					break;
				}
				#endif
				
				#if defined(STACK_USE_UDP)
				if(cIPFrameType == IP_PROT_UDP)
				{
					// Stop processing packets if we came upon a UDP frame with application data in it
					if(UDPProcess(&remoteNode, &tempLocalIP, dataCount))
						return;
				}
				#endif

				break;
		}
	}
}
Ejemplo n.º 8
0
/*
 * Main entry point.
 */
void main(void)
{
    static TICK8 t = 0;
    static TICK8 tmr10ms = 0;
    
    //Initialize any application specific hardware.
    InitializeBoard();

    //Initialize all stack related components. Following steps must
    //be performed for all applications using PICmicro TCP/IP Stack.
    TickInit();

    //Initialize file system.
    fsysInit();

    //Intialize HTTP Execution unit
    htpexecInit();

    //Initialze serial port
    serInit();
    
    //Initialize Stack and application related NV variables.
    appcfgInit();
    appcfgUSART();              //Configure the USART
    #ifdef SER_USE_INTERRUPT    //Interrupt enabled serial ports have to be enabled
    serEnable();
    #endif
    appcfgCpuIO();          //Configure the CPU's I/O port pin directions - input or output
    appcfgCpuIOValues();    //Configure the CPU's I/O port pin default values
    appcfgADC();            //Configure ADC unit
    appcfgPWM();            //Configure PWM Channels

    //Serial configuration menu - display it for configured time and allow user to enter configuration menu
    scfInit(appcfgGetc(APPCFG_STARTUP_SER_DLY));
    
    //LCD Display Initialize
    lcdInit();

    StackInit();

#if defined(STACK_USE_HTTP_SERVER)
    HTTPInit();
#endif

#if defined(STACK_USE_FTP_SERVER)
    FTPInit();
#endif

    //Initializes "UDP Command Port" and "UDP Command Responce Port".
    cmdUdpInit();

#if defined(STACK_USE_DHCP) || defined(STACK_USE_IP_GLEANING)
    DHCPReset();    //Initialize DHCP module
    
    //If DHCP is NOT enabled
    if ((appcfgGetc(APPCFG_NETFLAGS) & APPCFG_NETFLAGS_DHCP) == 0)
    {
        //Force IP address display update.
        myDHCPBindCount = 1;
        
        #if defined(STACK_USE_DHCP)
        DHCPDisable();
        #endif
    }
#endif

    #if (DEBUG_MAIN >= LOG_DEBUG)
        debugPutMsg(1); //@mxd:1:Starting main loop
    #endif

    /*
     * Once all items are initialized, go into infinite loop and let
     * stack items execute their tasks.
     * If application needs to perform its own task, it should be
     * done at the end of while loop.
     * Note that this is a "co-operative mult-tasking" mechanism
     * where every task performs its tasks (whether all in one shot
     * or part of it) and returns so that other tasks can do their
     * job.
     * If a task needs very long time to do its job, it must broken
     * down into smaller pieces so that other tasks can have CPU time.
     */
    while(1)
    {
        //Clear timer 1 every cycle, can be used to measure events. Has a overflow of 65ms.
        //Get delay in this function with:
        // TMR1L | (TMR1H<<8)
        TMR1H = 0;  //First write to TMR1H buffer!
        TMR1L = 0;  //This write will also update TMR1H with value written above to buffer

        //Blink SYSTEM LED every second.
        if (appcfgGetc(APPCFG_SYSFLAGS) & APPCFG_SYSFLAGS_BLINKB6) {
            if ( TickGetDiff8bit(t) >= ((TICK8)TICKS_PER_SECOND / (TICK8)2) )
            {
                t = TickGet8bit();
                TRISB_RB6 = 0;
                LATB6 ^= 1;
            }
        }
        
        //Enter each 10ms
        if ( TickGetDiff8bit(tmr10ms) >= ((TICK8)TICKS_PER_SECOND / (TICK8)100) )
        {
            tmr10ms = TickGet8bit();
        }
        
        //This task performs normal stack task including checking for incoming packet,
        //type of packet and calling appropriate stack entity to process it.
        StackTask();
        
        //Process "UDP Command Port" and "UDP Command Responce Port"
        cmdProcess();

#if defined(STACK_USE_HTTP_SERVER)
        //This is a TCP application.  It listens to TCP port 80
        //with one or more sockets and responds to remote requests.
        HTTPServer();
#endif

#if defined(STACK_USE_FTP_SERVER)
        FTPServer();
#endif

#if defined(STACK_USE_ANNOUNCE)
        DiscoveryTask();
#endif

#if defined(STACK_USE_NBNS)
        NBNSTask();
#endif

        //Add your application speicifc tasks here.
        ProcessIO();

        //For DHCP information, display how many times we have renewed the IP
        //configuration since last reset.
        if ( DHCPBindCount != myDHCPBindCount )
        {
            #if (DEBUG_MAIN >= LOG_INFO)
                debugPutMsg(2); //@mxd:2:DHCP Bind Count = %D
                debugPutByteHex(DHCPBindCount);
            #endif
            
            //Display new IP address
            #if (DEBUG_MAIN >= LOG_INFO)
                debugPutMsg(3); //@mxd:3:DHCP complete, IP = %D.%D.%D.%D
                debugPutByteHex(AppConfig.MyIPAddr.v[0]);
                debugPutByteHex(AppConfig.MyIPAddr.v[1]);
                debugPutByteHex(AppConfig.MyIPAddr.v[2]);
                debugPutByteHex(AppConfig.MyIPAddr.v[3]);
            #endif
            myDHCPBindCount = DHCPBindCount;
            
            #if defined(STACK_USE_ANNOUNCE)
                AnnounceIP();
            #endif             
        }
    }
}
Ejemplo n.º 9
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
        }
    }

}