Example #1
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( WF_CS_TRIS )
        // This task performs low-level MAC processing specific to the MRF24W
        MACProcess();
        #if defined( STACK_USE_EZ_CONFIG ) && !defined(__18CXX)
            WFEasyConfigMgr();
        #endif
        
       #if defined(STACK_USE_DHCP_CLIENT)
       
            #ifdef schDebug
               currentRoutine=STACKTASKDHCPCLIENT;
            #endif   
           // 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(g_DhcpRenew == TRUE)
              {
                 g_DhcpRenew = FALSE;
                  AppConfig.MyIPAddr.Val = AppConfig.DefaultIPAddr.Val;
                 AppConfig.MyMask.Val = AppConfig.DefaultMask.Val;
                 AppConfig.Flags.bInConfigMode = TRUE;
                 DHCPInit(0);
               g_DhcpRetryTimer = (UINT32)TickGet();
              } else {
                 if (g_DhcpRetryTimer && TickGet() - g_DhcpRetryTimer >= TICKS_PER_SECOND * 8) {
                  DHCPInit(0);
                  g_DhcpRetryTimer = (UINT32)TickGet();
                 }
              }
           
              // 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(0)) {
                 AppConfig.Flags.bInConfigMode = FALSE;
               g_DhcpRetryTimer = 0;
              }
           }
       #endif // STACK_USE_DHCP_CLIENT
        
    #endif // WF_CS_TRIS


   #if defined(STACK_USE_DHCP_CLIENT) && !defined(WF_CS_TRIS)
   // 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.
            #ifdef schDebug
               currentRoutine=STACKTASKDHCPCLIENTTRIS;
            #endif  
   
   if(AppConfig.Flags.bIsDHCPEnabled)
   {
      static BOOL bLastLinkState = FALSE;
      BOOL bCurrentLinkState;
      
      bCurrentLinkState = MACIsLinked();
      if(bCurrentLinkState != bLastLinkState)
      {
         bLastLinkState = bCurrentLinkState;
         if(!bCurrentLinkState)
         {
            AppConfig.MyIPAddr.Val = AppConfig.DefaultIPAddr.Val;
            AppConfig.MyMask.Val = AppConfig.DefaultMask.Val;
            AppConfig.Flags.bInConfigMode = TRUE;
            DHCPInit(0);
         }
      }
   
      // 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(0))
         AppConfig.Flags.bInConfigMode = FALSE;
          
   }
   #endif
   

    #if defined (STACK_USE_AUTO_IP)
    AutoIPTasks();
    #endif

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


   #if defined(STACK_USE_UDP)
            #ifdef schDebug
               currentRoutine=STACKTASKUDP;
            #endif  
   UDPTask();
   #endif

  #if defined(STACK_USE_CCS_GRATUITOUS_ARP)
   GratArpTask();
  #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)
             #ifdef schDebug
               currentRoutine=STACKTASKUDPDISCARD;
            #endif  
         UDPDiscard();
      #endif

      // Fetch a packet (throws old one away, if not thrown away 
      // yet)
      
            #ifdef schDebug
               currentRoutine=STACKTASKMACGETHEADER;
            #endif  
      if(!MACGetHeader(&remoteNode.MACAddr, &cFrameType))
         break;

      // When using a WiFi module, filter out all incoming packets that have 
      // the same source MAC address as our own MAC address.  This is to 
      // prevent receiving and passing our own broadcast packets up to other 
      // layers and avoid, for example, having our own gratuitous ARPs get 
      // answered by ourself.
      #if defined(WF_CS_TRIS)
            #ifdef schDebug
               currentRoutine=STACKTASKWFCSTRIS;
            #endif  
         if(memcmp((void*)&remoteNode.MACAddr, (void*)&AppConfig.MyMACAddr, 6) == 0u)
            continue;
      #endif
      
      #if defined(STACK_USE_CCS_RX_EVENT)
            #ifdef schDebug
               currentRoutine=STACKTASKCCSRX;
            #endif  
      STACK_USE_CCS_RX_EVENT();  //__CCS__
      #endif
      
      // Dispatch the packet to the appropriate handler
      switch(cFrameType)
      {
         case MAC_ARP:
            #ifdef schDebug
               currentRoutine=STACKTASKARP;
            #endif  
            ARPProcess();
            break;
   
         case MAC_IP:
            if(!IPGetHeader(&tempLocalIP, &remoteNode, &cIPFrameType, &dataCount))
               break;

            #if defined(STACK_USE_ICMP_SERVER) || defined(STACK_USE_ICMP_CLIENT)
            #ifdef schDebug
               currentRoutine=STACKTASKICMP;
            #endif  
            if(cIPFrameType == IP_PROT_ICMP)
            {
               #if defined(STACK_USE_IP_GLEANING)
               if(AppConfig.Flags.bInConfigMode && AppConfig.Flags.bIsDHCPEnabled)
               {
                  // According 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;
                  }
               }
               #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) ||
#if defined(STACK_USE_ZEROCONF_LINK_LOCAL) || defined(STACK_USE_ZEROCONF_MDNS_SD)
                                                (tempLocalIP.Val == 0xFB0000E0) ||
#endif
                  (tempLocalIP.Val == ((AppConfig.MyIPAddr.Val & AppConfig.MyMask.Val) | ~AppConfig.MyMask.Val)))
               {
                  ICMPProcess(&remoteNode, dataCount);
               }

               break;
            }
            #endif
            
            #if defined(STACK_USE_TCP)
            #ifdef schDebug
               currentRoutine=STACKTASKTCP2;
            #endif  
            if(cIPFrameType == IP_PROT_TCP)
            {
               TCPProcess(&remoteNode, &tempLocalIP, dataCount);
               break;
            }
            #endif
            
            #if defined(STACK_USE_UDP)
            #ifdef schDebug
               currentRoutine=STACKTASKUDP2;
            #endif  
            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;
      }
   }
}
Example #2
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;
		}
	}
}