Subversion Repositories HomeAutomation

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. /*********************************************************************
  2.  *
  3.  *               Microchip TCP/IP Stack FSM Implementation on PIC18
  4.  *
  5.  *********************************************************************
  6.  * FileName:        StackTsk.c
  7.  * Dependencies:    StackTsk.H
  8.  *                  ARPTsk.h
  9.  *                  MAC.h
  10.  *                  IP.h
  11.  *                  ICMP.h
  12.  *                  Tcp.h
  13.  *                  http.h
  14.  * Processor:       PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F
  15.  * Complier:        Microchip C18 v3.02 or higher
  16.  *                  Microchip C30 v2.01 or higher
  17.  * Company:         Microchip Technology, Inc.
  18.  *
  19.  * Software License Agreement
  20.  *
  21.  * This software is owned by Microchip Technology Inc. ("Microchip")
  22.  * and is supplied to you for use exclusively as described in the
  23.  * associated software agreement.  This software is protected by
  24.  * software and other intellectual property laws.  Any use in
  25.  * violation of the software license may subject the user to criminal
  26.  * sanctions as well as civil liability.  Copyright 2006 Microchip
  27.  * Technology Inc.  All rights reserved.
  28.  *
  29.  * This software is provided "AS IS."  MICROCHIP DISCLAIMS ALL
  30.  * WARRANTIES, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, NOT LIMITED
  31.  * TO MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
  32.  * INFRINGEMENT.  Microchip shall in no event be liable for special,
  33.  * incidental, or consequential damages.
  34.  *
  35.  *
  36.  * Author               Date        Comment
  37.  *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  38.  * Nilesh Rajbharti     8/14/01     Original (Rev. 1.0)
  39.  * Nilesh Rajbharti     2/9/02      Cleanup
  40.  * Nilesh Rajbharti     5/22/02     Rev 2.0 (See version.log for detail)
  41.  * Nilesh Rajbharti     12/5/02     Modified UDPProcess() and TCPProcess()
  42.  *                                  to include localIP as third param.
  43.  *                                  This was done to allow these functions
  44.  *                                  to calculate checksum correctly.
  45.  * Nilesh Rajbharti     7/26/04     Added code in StackTask() to not
  46.  *                                  clear statically IP address if link is
  47.  *                                  removed and DHCP module is disabled
  48.  *                                  at runtime.
  49. ********************************************************************/
  50.  
  51. #define STACK_INCLUDE
  52.  
  53. #include "..\Include\StackTsk.h"
  54. #include "..\Include\ARPTsk.h"
  55. #include "..\Include\MAC.h"
  56. #include "..\Include\IP.h"
  57.  
  58. #if defined(STACK_USE_TCP)
  59. #include "..\Include\TCP.h"
  60. #endif
  61.  
  62. #if defined(STACK_USE_HTTP_SERVER)
  63. #include "..\Include\HTTP.h"
  64. #endif
  65.  
  66. #if defined(STACK_USE_ICMP)
  67.     #include "..\Include\ICMP.h"
  68. #endif
  69.  
  70. #if defined(STACK_USE_UDP)
  71.     #include "..\Include\UDP.h"
  72. #endif
  73.  
  74. #if defined(STACK_USE_DHCP)
  75.     #include "..\Include\DHCP.h"
  76. #endif
  77.  
  78.     // myDHCPBindCount defined in MainDemo.c;  Used to force an IP
  79.     // address display update for IP Gleaning
  80.     extern BYTE myDHCPBindCount;
  81.  
  82.  
  83. /*
  84.  * Stack FSM states.
  85.  */
  86. typedef enum _SM_STACK
  87. {
  88.     SM_STACK_IDLE,
  89.     SM_STACK_MAC,
  90.     SM_STACK_IP,
  91.     SM_STACK_ICMP,
  92.     SM_STACK_ICMP_REPLY,
  93.     SM_STACK_ARP,
  94.     SM_STACK_TCP,
  95.     SM_STACK_UDP
  96. } SM_STACK;
  97. static SM_STACK smStack;
  98.  
  99. NODE_INFO remoteNode;
  100.  
  101.  
  102.  
  103. /*********************************************************************
  104.  * Function:        void StackInit(void)
  105.  *
  106.  * PreCondition:    None
  107.  *
  108.  * Input:           None
  109.  *
  110.  * Output:          Stack and its componets are initialized
  111.  *
  112.  * Side Effects:    None
  113.  *
  114.  * Note:            This function must be called before any of the
  115.  *                  stack or its component routines are used.
  116.  *
  117.  ********************************************************************/
  118. void StackInit(void)
  119. {
  120.     smStack                     = SM_STACK_IDLE;
  121.  
  122. #if defined(STACK_USE_IP_GLEANING) || defined(STACK_USE_DHCP)
  123.     /*
  124.      * If DHCP or IP Gleaning is enabled,
  125.      * startup in Config Mode.
  126.      */
  127.     AppConfig.Flags.bInConfigMode = TRUE;
  128.  
  129. #endif
  130.  
  131.     MACInit();
  132.  
  133.     ARPInit();
  134.  
  135. #if defined(STACK_USE_UDP)
  136.     UDPInit();
  137. #endif
  138.  
  139. #if defined(STACK_USE_TCP)
  140.     TCPInit();
  141. #endif
  142.  
  143. }
  144.  
  145.  
  146. /*********************************************************************
  147.  * Function:        void StackTask(void)
  148.  *
  149.  * PreCondition:    StackInit() is already called.
  150.  *
  151.  * Input:           None
  152.  *
  153.  * Output:          Stack FSM is executed.
  154.  *
  155.  * Side Effects:    None
  156.  *
  157.  * Note:            This FSM checks for new incoming packets,
  158.  *                  and routes it to appropriate stack components.
  159.  *                  It also performs timed operations.
  160.  *
  161.  *                  This function must be called periodically to
  162.  *                  ensure timely responses.
  163.  *
  164.  ********************************************************************/
  165. void StackTask(void)
  166. {
  167.     static WORD dataCount;
  168.  
  169. #if defined(STACK_USE_ICMP)
  170.     static BYTE data[MAX_ICMP_DATA_LEN];
  171.     static WORD ICMPId;
  172.     static WORD ICMPSeq;
  173. #endif
  174.     IP_ADDR tempLocalIP;
  175.  
  176.  
  177.     union
  178.     {
  179.         BYTE MACFrameType;
  180.         BYTE IPFrameType;
  181.         ICMP_CODE ICMPCode;
  182.     } type;
  183.  
  184.  
  185.     BOOL lbContinue;
  186.  
  187.     do
  188.     {
  189.         lbContinue = FALSE;
  190.  
  191.         switch(smStack)
  192.         {
  193.         case SM_STACK_IDLE:
  194.         case SM_STACK_MAC:
  195.  
  196.             if ( !MACGetHeader(&remoteNode.MACAddr, &type.MACFrameType) )
  197.             {
  198.                 #if defined(STACK_USE_DHCP)
  199.                     // Normally, an application would not include  DHCP module
  200.                     // if it is not enabled. But in case some one wants to disable
  201.                     // DHCP module at run-time, remember to not clear our IP
  202.                     // address if link is removed.
  203.                     if ( AppConfig.Flags.bIsDHCPEnabled )
  204.                     {
  205.                         if ( !MACIsLinked() )
  206.                         {
  207.                             AppConfig.MyIPAddr.Val = 0x00000000ul;
  208.                             AppConfig.Flags.bInConfigMode = TRUE;
  209.                             DHCPReset();
  210.                         }
  211.                     }
  212.                 #endif
  213.  
  214.                 break;
  215.             }
  216.  
  217.             lbContinue = TRUE;
  218.             if ( type.MACFrameType == MAC_IP )
  219.                 smStack = SM_STACK_IP;
  220.             else if ( type.MACFrameType == MAC_ARP )
  221.                 smStack = SM_STACK_ARP;
  222.             else
  223.                 MACDiscardRx();
  224.             break;
  225.  
  226.         case SM_STACK_ARP:
  227.             if ( ARPProcess() )
  228.                 smStack = SM_STACK_IDLE;
  229.             break;
  230.  
  231.         case SM_STACK_IP:
  232.             if ( IPGetHeader(&tempLocalIP,
  233.                              &remoteNode,
  234.                              &type.IPFrameType,
  235.                              &dataCount) )
  236.             {
  237.                 lbContinue = TRUE;
  238.                 if ( type.IPFrameType == IP_PROT_ICMP )
  239.                 {
  240.                     smStack = SM_STACK_ICMP;
  241.  
  242. #if defined(STACK_USE_IP_GLEANING)
  243.                     if(AppConfig.Flags.bInConfigMode && AppConfig.Flags.bIsDHCPEnabled)
  244.                     {
  245.                         /*
  246.                          * Accoriding to "IP Gleaning" procedure,
  247.                          * when we receive an ICMP packet with a valid
  248.                          * IP address while we are still in configuration
  249.                          * mode, accept that address as ours and conclude
  250.                          * configuration mode.
  251.                          */
  252.                         if( tempLocalIP.Val != 0xffffffff )
  253.                         {
  254.                             AppConfig.Flags.bInConfigMode = FALSE;
  255.                             AppConfig.MyIPAddr = tempLocalIP;
  256.                             myDHCPBindCount--;
  257.                         }
  258.                     }
  259. #endif
  260.                 }
  261.  
  262. #if defined(STACK_USE_TCP)
  263.                 else if ( type.IPFrameType == IP_PROT_TCP )
  264.                     smStack = SM_STACK_TCP;
  265. #endif
  266.  
  267. #if defined(STACK_USE_UDP)
  268.                 else if ( type.IPFrameType == IP_PROT_UDP )
  269.                     smStack = SM_STACK_UDP;
  270. #endif
  271.  
  272.                 else    // Unknown/unsupported higher level protocol
  273.                 {
  274.                     lbContinue = FALSE;
  275.                     MACDiscardRx();
  276.  
  277.                     smStack = SM_STACK_IDLE;
  278.                 }
  279.             }
  280.             else    // Improper IP header version or checksum
  281.             {
  282.                 MACDiscardRx();
  283.                 smStack = SM_STACK_IDLE;
  284.             }
  285.             break;
  286.  
  287. #if defined(STACK_USE_UDP)
  288.         case SM_STACK_UDP:
  289.             if ( UDPProcess(&remoteNode, &tempLocalIP, dataCount) )
  290.                 smStack = SM_STACK_IDLE;
  291.             break;
  292. #endif
  293.  
  294. #if defined(STACK_USE_TCP)
  295.         case SM_STACK_TCP:
  296.             if ( TCPProcess(&remoteNode, &tempLocalIP, dataCount) )
  297.                 smStack = SM_STACK_IDLE;
  298.             break;
  299. #endif
  300.  
  301.         case SM_STACK_ICMP:
  302.             smStack = SM_STACK_IDLE;
  303.  
  304. #if defined(STACK_USE_ICMP)
  305.             if ( dataCount <= (MAX_ICMP_DATA_LEN+8) )
  306.             {
  307.                 if ( ICMPGet(&type.ICMPCode,
  308.                              data,
  309.                              (BYTE*)&dataCount,
  310.                              &ICMPId,
  311.                              &ICMPSeq) )
  312.                 {
  313.                     if ( type.ICMPCode == ICMP_ECHO_REQUEST )
  314.                     {
  315.                         lbContinue = TRUE;
  316.                         smStack = SM_STACK_ICMP_REPLY;
  317.                     }
  318.                 }
  319.             }
  320. #endif
  321.             MACDiscardRx();
  322.             break;
  323.  
  324. #if defined(STACK_USE_ICMP)
  325.         case SM_STACK_ICMP_REPLY:
  326.             if ( ICMPIsTxReady() )
  327.             {
  328.                 ICMPPut(&remoteNode,
  329.                         ICMP_ECHO_REPLY,
  330.                         data,
  331.                         (BYTE)dataCount,
  332.                         ICMPId,
  333.                         ICMPSeq);
  334.  
  335.                 smStack = SM_STACK_IDLE;
  336.             }
  337.             break;
  338. #endif
  339.  
  340.         }
  341.  
  342.     } while(lbContinue);
  343.  
  344. #if defined(STACK_USE_TCP)
  345.     // Perform timed TCP FSM.
  346.     TCPTick();
  347. #endif
  348.  
  349.  
  350. #if defined(STACK_USE_DHCP)
  351.     /*
  352.      * DHCP must be called all the time even after IP configuration is
  353.      * discovered.
  354.      * DHCP has to account lease expiration time and renew the configuration
  355.      * time.
  356.      */
  357.     DHCPTask();
  358.  
  359.     if(DHCPIsBound())
  360.         AppConfig.Flags.bInConfigMode = FALSE;
  361.  
  362. #endif
  363. }
  364.  
  365.