Subversion Repositories HomeAutomation

Rev

Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
363 johboh 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