Subversion Repositories HomeAutomation

Rev

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

Rev Author Line No. Line
363 johboh 1
/*********************************************************************
2
 *
3
 *                  ICMP Module for Microchip TCP/IP Stack
4
 *
5
 *********************************************************************
6
 * FileName:        ICMP.c
7
 * Dependencies:    ICMP.h
8
 *                  string.h
9
 *                  StackTsk.h
10
 *                  Helpers.h
11
 *                  IP.h
12
 *                  MAC.h
13
 * Processor:       PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F
14
 * Complier:        Microchip C18 v3.02 or higher
15
 *                  Microchip C30 v2.01 or higher
16
 * Company:         Microchip Technology, Inc.
17
 *
18
 * Software License Agreement
19
 *
20
 * This software is owned by Microchip Technology Inc. ("Microchip")
21
 * and is supplied to you for use exclusively as described in the
22
 * associated software agreement.  This software is protected by
23
 * software and other intellectual property laws.  Any use in
24
 * violation of the software license may subject the user to criminal
25
 * sanctions as well as civil liability.  Copyright 2006 Microchip
26
 * Technology Inc.  All rights reserved.
27
 *
28
 * This software is provided "AS IS."  MICROCHIP DISCLAIMS ALL
29
 * WARRANTIES, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, NOT LIMITED
30
 * TO MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
31
 * INFRINGEMENT.  Microchip shall in no event be liable for special,
32
 * incidental, or consequential damages.
33
 *
34
 *
35
 * Author               Date    Comment
36
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37
 * Nilesh Rajbharti     4/30/01 Original        (Rev 1.0)
38
 * Nilesh Rajbharti     2/9/02  Cleanup
39
 * Nilesh Rajbharti     5/22/02 Rev 2.0 (See version.log for detail)
40
 * Howard Schlunder     9/9/04  Added ENC28J60 DMA checksum support
41
 * Howard Schlunder     1/5/06  Increased DMA checksum efficiency
42
 ********************************************************************/
43
 
44
#include <string.h>
45
#include "..\Include\StackTsk.h"
46
#include "..\Include\Helpers.h"
47
#include "..\Include\ICMP.h"
48
#include "..\Include\IP.h"
49
#include "..\Include\MAC.h"
50
 
51
#if defined(STACK_USE_ICMP)
52
 
53
 
54
// ICMP packet definition
55
typedef struct _ICMP_PACKET
56
{
57
    BYTE    Type;
58
    BYTE    Code;
59
    WORD    Checksum;
60
    WORD    Identifier;
61
    WORD    SequenceNumber;
62
    BYTE    Data[MAX_ICMP_DATA];
63
} ICMP_PACKET;
64
#define ICMP_HEADER_SIZE    (sizeof(ICMP_PACKET) - MAX_ICMP_DATA)
65
 
66
static void SwapICMPPacket(ICMP_PACKET* p);
67
 
68
 
69
/*********************************************************************
70
 * Function:        BOOL ICMPGet(ICMP_CODE *code,
71
 *                              BYTE *data,
72
 *                              BYTE *len,
73
 *                              WORD *id,
74
 *                              WORD *seq)
75
 *
76
 * PreCondition:    MAC buffer contains ICMP type packet.
77
 *
78
 * Input:           code    - Buffer to hold ICMP code value
79
 *                  data    - Buffer to hold ICMP data
80
 *                  len     - Buffer to hold ICMP data length
81
 *                  id      - Buffer to hold ICMP id
82
 *                  seq     - Buffer to hold ICMP seq
83
 *
84
 * Output:          TRUE if valid ICMP packet was received
85
 *                  FALSE otherwise.
86
 *
87
 * Side Effects:    None
88
 *
89
 * Overview:        None
90
 *
91
 * Note:            None
92
 ********************************************************************/
93
BOOL ICMPGet(ICMP_CODE *code,
94
             BYTE *data,
95
             BYTE *len,
96
             WORD *id,
97
             WORD *seq)
98
{
99
    ICMP_PACKET packet;
100
    WORD CalcChecksum;
101
    WORD ReceivedChecksum;
102
#if defined(NON_MCHP_MAC)
103
    WORD checksums[2];
104
#endif
105
 
106
    // Obtain the ICMP Header
107
    MACGetArray((BYTE*)&packet, ICMP_HEADER_SIZE);
108
 
109
 
110
#if !defined(NON_MCHP_MAC)
111
    // Calculate the checksum using the Microchip MAC's DMA module
112
    // The checksum data includes the precomputed checksum in the 
113
    // header, so a valid packet will always have a checksum of 
114
    // 0x0000 if the packet is not disturbed.
115
    ReceivedChecksum = 0x0000;
116
    CalcChecksum = MACCalcRxChecksum(0+sizeof(IP_HEADER), *len);
117
#endif
118
 
119
    // Obtain the ICMP data payload
120
    *len -= ICMP_HEADER_SIZE;
121
    MACGetArray(data, *len);
122
 
123
#if defined(NON_MCHP_MAC)
124
    // Calculte the checksum in local memory without hardware help
125
    ReceivedChecksum = packet.Checksum;
126
    packet.Checksum = 0;
127
 
128
    checksums[0] = ~CalcIPChecksum((BYTE*)&packet, ICMP_HEADER_SIZE);
129
    checksums[1] = ~CalcIPChecksum(data, *len);
130
 
131
    CalcChecksum = CalcIPChecksum((BYTE*)checksums, 2 * sizeof(WORD));
132
#endif
133
 
134
 
135
    SwapICMPPacket(&packet);
136
 
137
    *code = packet.Type;
138
    *id = packet.Identifier;
139
    *seq = packet.SequenceNumber;
140
 
141
    return ( CalcChecksum == ReceivedChecksum );
142
}
143
 
144
/*********************************************************************
145
 * Function:        void ICMPPut(NODE_INFO *remote,
146
 *                               ICMP_CODE code,
147
 *                               BYTE *data,
148
 *                               BYTE len,
149
 *                               WORD id,
150
 *                               WORD seq)
151
 *
152
 * PreCondition:    ICMPIsTxReady() == TRUE
153
 *
154
 * Input:           remote      - Remote node info
155
 *                  code        - ICMP_ECHO_REPLY or ICMP_ECHO_REQUEST
156
 *                  data        - Data bytes
157
 *                  len         - Number of bytes to send
158
 *                  id          - ICMP identifier
159
 *                  seq         - ICMP sequence number
160
 *
161
 * Output:          None
162
 *
163
 * Side Effects:    None
164
 *
165
 * Note:            A ICMP packet is created and put on MAC.
166
 *
167
 ********************************************************************/
168
void ICMPPut(NODE_INFO *remote,
169
             ICMP_CODE code,
170
             BYTE *data,
171
             BYTE len,
172
             WORD id,
173
             WORD seq)
174
{
175
    ICMP_PACKET packet;
176
    WORD ICMPLen;
177
    BUFFER MyTxBuffer = MACGetTxBuffer(TRUE);
178
 
179
    // Abort if there is no where in the Ethernet controller to 
180
    // store this packet.
181
    if(MyTxBuffer == INVALID_BUFFER)
182
        return;
183
 
184
    IPSetTxBuffer(MyTxBuffer, 0);
185
 
186
 
187
    ICMPLen = ICMP_HEADER_SIZE + (WORD)len;
188
 
189
    packet.Code             = 0;
190
    packet.Type             = code;
191
    packet.Checksum         = 0;
192
    packet.Identifier       = id;
193
    packet.SequenceNumber   = seq;
194
 
195
    memcpy((void*)packet.Data, (void*)data, len);
196
 
197
    SwapICMPPacket(&packet);
198
 
199
#if defined(NON_MCHP_MAC)
200
    packet.Checksum         = CalcIPChecksum((BYTE*)&packet,
201
                                    ICMPLen);
202
#endif
203
 
204
    IPPutHeader(remote,
205
                IP_PROT_ICMP,
206
                (WORD)(ICMP_HEADER_SIZE + len));
207
 
208
    IPPutArray((BYTE*)&packet, ICMPLen);
209
 
210
#if !defined(NON_MCHP_MAC)
211
    // Calculate and write the ICMP checksum using the Microchip MAC's DMA
212
    packet.Checksum = MACCalcTxChecksum(sizeof(IP_HEADER), ICMPLen);
213
    IPSetTxBuffer(MyTxBuffer, 2);
214
    MACPutArray((BYTE*)&packet.Checksum, 2);
215
#endif
216
 
217
 
218
    MACFlush();
219
}
220
 
221
/*********************************************************************
222
 * Function:        void SwapICMPPacket(ICMP_PACKET* p)
223
 *
224
 * PreCondition:    None
225
 *
226
 * Input:           p - ICMP packet header
227
 *
228
 * Output:          ICMP packet is swapped
229
 *
230
 * Side Effects:    None
231
 *
232
 * Overview:        None
233
 *
234
 * Note:            None
235
 ********************************************************************/
236
static void SwapICMPPacket(ICMP_PACKET* p)
237
{
238
    p->Identifier           = swaps(p->Identifier);
239
    p->SequenceNumber       = swaps(p->SequenceNumber);
240
    p->Checksum             = swaps(p->Checksum);
241
}
242
 
243
 
244
#endif //#if defined(STACK_USE_ICMP)