Esempio 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 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();
}
/**
 * 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();
}
Esempio 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
}