/[H8]/trunk/docs/Microchip TCP_IP stack/TCPIP Stack/UDP.c
ViewVC logotype

Annotation of /trunk/docs/Microchip TCP_IP stack/TCPIP Stack/UDP.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 15 - (hide annotations) (download)
Thu Apr 19 09:01:15 2007 UTC (17 years, 2 months ago) by hedin
File MIME type: text/plain
File size: 23909 byte(s)
added the TCP/IP stack, source code.
1 hedin 15 /*********************************************************************
2     *
3     * User Datagram Protocol (UDP) Communications Layer
4     * Module for Microchip TCP/IP Stack
5     * -Provides unreliable, minimum latency transport of application
6     * datagram (packet) oriented data
7     * -Reference: RFC 768
8     *
9     *********************************************************************
10     * FileName: UDP.c
11     * Dependencies: StackTsk.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     * Copyright © 2002-2007 Microchip Technology Inc. All rights
21     * reserved.
22     *
23     * Microchip licenses to you the right to use, modify, copy, and
24     * distribute:
25     * (i) the Software when embedded on a Microchip microcontroller or
26     * digital signal controller product (“Device”) which is
27     * integrated into Licensee’s product; or
28     * (ii) ONLY the Software driver source files ENC28J60.c and
29     * ENC28J60.h ported to a non-Microchip device used in
30     * conjunction with a Microchip ethernet controller for the
31     * sole purpose of interfacing with the ethernet controller.
32     *
33     * You should refer to the license agreement accompanying this
34     * Software for additional information regarding your rights and
35     * obligations.
36     *
37     * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” WITHOUT
38     * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
39     * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
40     * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
41     * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR
42     * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
43     * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
44     * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
45     * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
46     * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
47     * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
48     *
49     *
50     * Author Date Comment
51     *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
52     * Nilesh Rajbharti 3/19/01 Original (Rev 1.0)
53     * Nilesh Rajbharti 2/26/03 Fixed UDPGet and UDPProcess bugs
54     * as discovered and fixed by John Owen
55     * of Powerwave.
56     * 1. UDPGet would return FALSE on last good byte
57     * 2. UDPProcess was incorrectly calculating length.
58     * Nilesh Rajbharti 5/19/03 Added bFirstRead flag similar to TCP
59     * to detect very first UDPGet and
60     * reset MAC Rx pointer to begining of
61     * UDP data area. This would ensure that
62     * if UDP socket has pending Rx data and
63     * another module resets MAC Rx pointer,
64     * next UDP socket Get would get correct
65     * data.
66     * Robert Sloan (RSS) 5/29/03 Improved FindMatchingSocket()
67     * Nilesh Rajbharti 12/2/03 Added UDPChecksum logic in UDPProcess()
68     * Nilesh Rajbharti 12/5/03 Modified UDPProcess() and FindMatchingSocket()
69     * to include localIP as new parameter.
70     * This corrects pseudo header checksum
71     * logic in UDPProcess().
72     * It also corrects broadcast packet
73     * matching correct in FindMatchingSocket().
74     * Howard Schlunder 1/16/06 Fixed an imporbable RX checksum bug
75     * when using a Microchip Ethernet controller)
76     * Howard Schlunder 6/02/06 Fixed a bug where all RXed UDP packets
77     * without a checksum (0x0000) were thrown
78     * away. No checksum is legal in UDP.
79     * Howard Schlunder 8/10/06 Fixed a bug where UDP sockets would
80     * unintentionally keep the remote MAC
81     * address cached, even after calling
82     * UDPInit(), UDPClose(), or reseting
83     * the part without clearing all the
84     * PICmicro memory.
85     ********************************************************************/
86     #define __UDP_C
87    
88     #include "TCPIP Stack/TCPIP.h"
89    
90     #if defined(STACK_USE_UDP)
91    
92     #define LOCAL_UDP_PORT_START_NUMBER (50000u)
93     #define LOCAL_UDP_PORT_END_NUMBER (51999u)
94    
95    
96     UDP_SOCKET_INFO UDPSocketInfo[MAX_UDP_SOCKETS];
97     UDP_SOCKET activeUDPSocket;
98     static UDP_SOCKET LastPutSocket = INVALID_UDP_SOCKET;
99    
100     static UDP_SOCKET FindMatchingSocket(UDP_HEADER *h, NODE_INFO *remoteNode,
101     IP_ADDR *localIP);
102    
103     /*********************************************************************
104     * Function: void UDPInit(void)
105     *
106     * PreCondition: None
107     *
108     * Input: None
109     *
110     * Output: None
111     *
112     * Side Effects: None
113     *
114     * Overview: Initializes internal variables.
115     *
116     * Note:
117     ********************************************************************/
118     void UDPInit(void)
119     {
120     UDP_SOCKET s;
121    
122     for ( s = 0; s < MAX_UDP_SOCKETS; s++ )
123     {
124     UDPClose(s);
125     }
126     }
127    
128     /*********************************************************************
129     * Function: UDP_SOCKET UDPOpen(UDP_PORT localPort,
130     * NODE_INFO *remoteNode,
131     * UDP_PORT remotePort)
132     *
133     * PreCondition: UDPInit() is already called
134     *
135     * Input: remoteNode - Remote Node info such as MAC and IP
136     * address
137     * If NULL, broadcast node address is set.
138     * remotePort - Remote Port to which to talk to
139     * If INVALID_UDP_SOCKET, localPort is
140     * opened for Listen.
141     * localPort - A valid port number or 0x0000 if
142     * dynamic assignment is desired.
143     *
144     * Output: On success: A UDP socket handle that can be used
145     * for subsequent UDP API calls.
146     * On failure: INVALID_UDP_SOCKET
147     *
148     * Side Effects: None
149     *
150     * Overview: A UDP socket is allocated and parameters are stored.
151     *
152     * Note: If the localPort is not specified, a unique port
153     * number is automatically assigned.
154     ********************************************************************/
155     UDP_SOCKET UDPOpen(UDP_PORT localPort,
156     NODE_INFO *remoteNode,
157     UDP_PORT remotePort)
158     {
159     UDP_SOCKET s;
160     UDP_SOCKET_INFO *p;
161    
162     // Local temp port numbers.
163     static WORD NextPort __attribute__((persistent));
164    
165    
166     p = UDPSocketInfo;
167     for ( s = 0; s < MAX_UDP_SOCKETS; s++ )
168     {
169     if(p->localPort == INVALID_UDP_PORT)
170     {
171     p->localPort = localPort;
172    
173     if(localPort == 0x0000u)
174     {
175     if(NextPort > LOCAL_UDP_PORT_END_NUMBER || NextPort < LOCAL_UDP_PORT_START_NUMBER)
176     NextPort = LOCAL_UDP_PORT_START_NUMBER;
177    
178     p->localPort = NextPort++;
179     }
180    
181     // If remoteNode is supplied, remember it.
182     if(remoteNode)
183     {
184     memcpy((void*)&p->remoteNode,
185     (const void*)remoteNode,
186     sizeof(p->remoteNode));
187     }
188     else
189     {
190     // else Set broadcast address
191     memset((void*)&p->remoteNode, 0xFF, sizeof(p->remoteNode));
192     }
193    
194     p->remotePort = remotePort;
195     p->TxCount = 0;
196     p->RxCount = 0;
197    
198     // Mark this socket as active.
199     // Once an active socket is set, subsequent operation can be
200     // done without explicitely supply socket identifier.
201     activeUDPSocket = s;
202     return s;
203     }
204     p++;
205     }
206    
207     return (UDP_SOCKET)INVALID_UDP_SOCKET;
208     }
209    
210    
211    
212    
213     /*********************************************************************
214     * Function: void UDPClose(UDP_SOCKET s)
215     *
216     * PreCondition: UDPOpen() is already called
217     *
218     * Input: s - Socket that is to be closed.
219     *
220     * Output: None
221     *
222     * Side Effects: None
223     *
224     * Overview: Given socket is marked as available for future
225     * new communcations.
226     *
227     * Note: This function does not affect previous
228     * active UDP socket designation.
229     ********************************************************************/
230     void UDPClose(UDP_SOCKET s)
231     {
232     UDPSocketInfo[s].localPort = INVALID_UDP_PORT;
233     UDPSocketInfo[s].remoteNode.IPAddr.Val = 0x00000000;
234     UDPSocketInfo[s].Flags.bFirstRead = FALSE;
235     }
236    
237    
238     /*********************************************************************
239     * Function: BOOL UDPIsPutReady(UDP_SOCKET s)
240     *
241     * PreCondition:
242     *
243     * Input: s - Socket that is to be loaded and made
244     * an active UDP socket.
245     *
246     * Output: WORD: Number of bytes that can be put, 0 if none
247     *
248     * Side Effects: None
249     *
250     * Overview: None
251     *
252     * Note: This call sets given socket as an active UDP socket.
253     ********************************************************************/
254     WORD UDPIsPutReady(UDP_SOCKET s)
255     {
256     if(LastPutSocket != s)
257     {
258     LastPutSocket = s;
259     MACSetWritePtr(BASE_TX_ADDR + sizeof(ETHER_HEADER) + sizeof(IP_HEADER) + sizeof(UDP_HEADER));
260     UDPSocketInfo[s].TxCount = 0;
261     }
262    
263     activeUDPSocket = s;
264     if(!MACIsTxReady())
265     return 0;
266    
267     return MAC_TX_BUFFER_SIZE - sizeof(IP_HEADER) - sizeof(UDP_HEADER) - UDPSocketInfo[activeUDPSocket].TxCount;
268     }
269    
270     /*********************************************************************
271     * Function: BOOL UDPPut(BYTE v)
272     *
273     * PreCondition: UDPIsPutReady() > 0 with desired UDP socket
274     * that is to be loaded.
275     *
276     * Input: v - Data byte to loaded into transmit buffer
277     *
278     * Output: TRUE if put successful
279     * FALSE if transmit buffer is full and put failed
280     *
281     * Side Effects: None
282     *
283     * Overview: Given data byte is put into UDP transmit buffer
284     * and active UDP socket buffer length is incremented
285     * by one.
286     * If buffer has become full, FALSE is returned.
287     * Or else TRUE is returned.
288     *
289     * Note: This function loads data into an active UDP socket
290     * as determined by previous call to UDPIsPutReady()
291     ********************************************************************/
292     BOOL UDPPut(BYTE v)
293     {
294     // See if we are out of transmit space.
295     if(UDPSocketInfo[activeUDPSocket].TxCount >= (MAC_TX_BUFFER_SIZE - sizeof(IP_HEADER) - sizeof(UDP_HEADER)))
296     {
297     return FALSE;
298     }
299    
300     // Load application data byte
301     MACPut(v);
302     UDPSocketInfo[activeUDPSocket].TxCount++;
303    
304     return TRUE;
305     }
306    
307     /*********************************************************************
308     * Function: WORD UDPPutArray(BYTE *cData, WORD wDataLen)
309     *
310     * PreCondition: UDPIsPutReady() > 0 with desired UDP socket
311     * that is to be loaded.
312     *
313     * Input: *cData - Pointer to data to write
314     * wDataLen - Length of data @ *cData to write
315     *
316     * Output: WORD: Number of bytes successfully placed in the
317     * UDP transmit buffer
318     *
319     * Side Effects: None
320     *
321     * Overview: None
322     *
323     * Note: None
324     ********************************************************************/
325     WORD UDPPutArray(BYTE *cData, WORD wDataLen)
326     {
327     WORD wTemp;
328    
329     wTemp = (MAC_TX_BUFFER_SIZE - sizeof(IP_HEADER) - sizeof(UDP_HEADER)) - UDPSocketInfo[activeUDPSocket].TxCount;
330     if(wTemp < wDataLen)
331     wDataLen = wTemp;
332    
333     UDPSocketInfo[activeUDPSocket].TxCount += wDataLen;
334    
335     // Load application data bytes
336     MACPutArray(cData, wDataLen);
337    
338     return wDataLen;
339     }
340    
341     WORD UDPPutROMArray(ROM BYTE *cData, WORD wDataLen)
342     {
343     WORD wTemp;
344    
345     wTemp = (MAC_TX_BUFFER_SIZE - sizeof(IP_HEADER) - sizeof(UDP_HEADER)) - UDPSocketInfo[activeUDPSocket].TxCount;
346     if(wTemp < wDataLen)
347     wDataLen = wTemp;
348    
349     UDPSocketInfo[activeUDPSocket].TxCount += wDataLen;
350    
351     // Load application data bytes
352     MACPutROMArray(cData, wDataLen);
353    
354     return wDataLen;
355     }
356    
357     BYTE* UDPPutString(BYTE *strData)
358     {
359     return strData + UDPPutArray(strData, strlen((char*)strData));
360     }
361    
362     ROM BYTE* UDPPutROMString(ROM BYTE *strData)
363     {
364     return strData + UDPPutROMArray(strData, strlenpgm((ROM char*)strData));
365     }
366    
367    
368    
369     /*********************************************************************
370     * Function: BOOL UDPFlush(void)
371     *
372     * PreCondition: UDPPut() is already called and desired UDP socket
373     * is set as an active socket by calling
374     * UDPIsPutReady().
375     *
376     * Input: None
377     *
378     * Output: All and any data associated with active UDP socket
379     * buffer is marked as ready for transmission.
380     *
381     * Side Effects: None
382     *
383     * Overview: None
384     *
385     * Note: This function transmit all data from
386     * an active UDP socket.
387     ********************************************************************/
388     void UDPFlush(void)
389     {
390     UDP_HEADER h;
391     UDP_SOCKET_INFO *p;
392    
393     // Wait for TX hardware to become available (finish transmitting
394     // any previous packet)
395     while(!IPIsTxReady());
396    
397     p = &UDPSocketInfo[activeUDPSocket];
398    
399    
400     h.SourcePort = swaps(p->localPort);
401     h.DestinationPort = swaps(p->remotePort);
402     h.Length = (WORD)((WORD)p->TxCount + (WORD)sizeof(UDP_HEADER));
403     // Do not swap h.Length yet. It is needed in IPPutHeader.
404     h.Checksum = 0x0000;
405    
406     MACSetWritePtr(BASE_TX_ADDR + sizeof(ETHER_HEADER));
407    
408     // Load IP header.
409     IPPutHeader( &p->remoteNode,
410     IP_PROT_UDP,
411     h.Length );
412    
413    
414     // Now swap h.Length.
415     h.Length = swaps(h.Length);
416    
417     // Now load UDP header.
418     IPPutArray((BYTE*)&h, sizeof(h));
419    
420     // Update checksum.
421     // TO BE IMPLEMENTED
422    
423     MACFlush();
424    
425     p->TxCount = 0;
426     LastPutSocket = INVALID_UDP_SOCKET;
427     }
428    
429    
430    
431     /*********************************************************************
432     * Function: WORD UDPIsGetReady(UDP_SOCKET s)
433     *
434     * PreCondition: UDPInit() is already called.
435     *
436     * Input: A valid UDP socket that is already "Listen"ed on
437     * or opened.
438     *
439     * Output: WORD: Number of available bytes that can be
440     * retrieved. 0 if no data received on this socket.
441     *
442     * Side Effects: Given socket is set as an active UDP Socket.
443     *
444     * Overview: None
445     *
446     * Note: This function automatically sets supplied socket
447     * as an active socket. Caller need not call
448     * explicit function UDPSetActiveSocket(). All
449     * subsequent calls will us this socket as an
450     * active socket.
451     ********************************************************************/
452     WORD UDPIsGetReady(UDP_SOCKET s)
453     {
454     activeUDPSocket = s;
455     return UDPSocketInfo[activeUDPSocket].RxCount;
456     }
457    
458     /*********************************************************************
459     * Function: BOOL UDPGet(BYTE *v)
460     *
461     * PreCondition: UDPInit() is already called AND
462     * UDPIsGetReady(s) > 0
463     *
464     * Input: v - Buffer to receive UDP data byte
465     *
466     * Output: TRUE if a data byte was read
467     * FALSE if no data byte was read or available
468     *
469     * Side Effects: None
470     *
471     * Overview: None
472     *
473     * Note: This function fetches data from an active UDP
474     * socket as set by UDPIsGetReady() call.
475     ********************************************************************/
476     BOOL UDPGet(BYTE *v)
477     {
478     // Make sure that there is data to return
479     if ( UDPSocketInfo[activeUDPSocket].RxCount == 0u )
480     return FALSE;
481    
482     // If if this very first read to packet, set MAC Rx Pointer to
483     // beginig of UDP data area.
484     if ( UDPSocketInfo[activeUDPSocket].Flags.bFirstRead )
485     {
486     UDPSocketInfo[activeUDPSocket].Flags.bFirstRead = FALSE;
487     UDPSetRxBuffer(0);
488     }
489    
490     *v = MACGet();
491    
492     UDPSocketInfo[activeUDPSocket].RxCount--;
493    
494     if ( UDPSocketInfo[activeUDPSocket].RxCount == 0u )
495     {
496     MACDiscardRx();
497     }
498    
499     return TRUE;
500     }
501    
502     /*********************************************************************
503     * Function: WORD UDPGetArray(BYTE *cData, WORD wDataLen)
504     *
505     * PreCondition: UDPInit() is already called AND
506     * UDPIsGetReady(s) > 0
507     *
508     * Input: *cData - Pointer to location to write retrieved bytes
509     * wDataLen - Number of bytes to retreive
510     *
511     * Output: WORD - Number of bytes written to cData
512     *
513     * Side Effects: None
514     *
515     * Overview: None
516     *
517     * Note: This function fetches data from an active UDP
518     * socket as set by UDPIsGetReady()
519     ********************************************************************/
520     WORD UDPGetArray(BYTE *cData, WORD wDataLen)
521     {
522     // If this is the very first read of the packet, set MAC Rx Pointer to
523     // beginig of UDP data area.
524     if(UDPSocketInfo[activeUDPSocket].Flags.bFirstRead)
525     {
526     UDPSocketInfo[activeUDPSocket].Flags.bFirstRead = FALSE;
527     UDPSetRxBuffer(0);
528     }
529    
530     // Make sure that there is data to return
531     if(UDPSocketInfo[activeUDPSocket].RxCount < wDataLen)
532     wDataLen = UDPSocketInfo[activeUDPSocket].RxCount;
533    
534     wDataLen = MACGetArray(cData, wDataLen);
535    
536     UDPSocketInfo[activeUDPSocket].RxCount -= wDataLen;
537    
538     if(UDPSocketInfo[activeUDPSocket].RxCount == 0u)
539     {
540     MACDiscardRx();
541     }
542    
543     return wDataLen;
544     }
545    
546     /*********************************************************************
547     * Function: void UDPDiscard(void)
548     *
549     * PreCondition: UDPInit() is already called
550     *
551     * Input: None
552     *
553     * Output: None
554     *
555     * Side Effects: None
556     *
557     * Overview: None
558     *
559     * Note: This function discards an active UDP socket content.
560     ********************************************************************/
561     void UDPDiscard(void)
562     {
563     if(UDPSocketInfo[activeUDPSocket].RxCount)
564     MACDiscardRx();
565    
566     UDPSocketInfo[activeUDPSocket].RxCount = 0;
567     }
568    
569    
570    
571     /*********************************************************************
572     * Function: BOOL UDPProcess(NODE_INFO* remoteNode,
573     * IP_ADDR *localIP,
574     * WORD len)
575     *
576     * PreCondition: UDPInit() is already called AND
577     * UDP segment is ready in MAC buffer
578     *
579     * Input: remoteNode - Remote node info
580     * len - Total length of UDP semgent.
581     *
582     * Output: TRUE if this function has completed its task
583     * FALSE otherwise
584     *
585     * Side Effects: None
586     *
587     * Overview: None
588     *
589     * Note: None
590     ********************************************************************/
591     // Pseudo header as defined by rfc 793.
592     typedef struct _PSEUDO_HEADER
593     {
594     IP_ADDR SourceAddress;
595     IP_ADDR DestAddress;
596     BYTE Zero;
597     BYTE Protocol;
598     WORD Length;
599     } PSEUDO_HEADER;
600    
601     #define SwapPseudoHeader(h) (h.Length = swaps(h.Length))
602    
603     BOOL UDPProcess(NODE_INFO *remoteNode, IP_ADDR *localIP, WORD len)
604     {
605     UDP_HEADER h;
606     UDP_SOCKET s;
607     PSEUDO_HEADER pseudoHeader;
608     DWORD_VAL checksums;
609    
610    
611     // Retrieve UDP header.
612     MACGetArray((BYTE*)&h, sizeof(h));
613    
614     h.SourcePort = swaps(h.SourcePort);
615     h.DestinationPort = swaps(h.DestinationPort);
616     h.Length = swaps(h.Length) - sizeof(UDP_HEADER);
617    
618     // See if we need to validate the checksum field (0x0000 is disabled)
619     if(h.Checksum)
620     {
621     // Calculate IP pseudoheader checksum.
622     pseudoHeader.SourceAddress = remoteNode->IPAddr;
623     pseudoHeader.DestAddress.v[0] = localIP->v[0];
624     pseudoHeader.DestAddress.v[1] = localIP->v[1];
625     pseudoHeader.DestAddress.v[2] = localIP->v[2];
626     pseudoHeader.DestAddress.v[3] = localIP->v[3];
627     pseudoHeader.Zero = 0x0;
628     pseudoHeader.Protocol = IP_PROT_UDP;
629     pseudoHeader.Length = len;
630    
631     SwapPseudoHeader(pseudoHeader);
632    
633     checksums.w[0] = ~CalcIPChecksum((BYTE*)&pseudoHeader,
634     sizeof(pseudoHeader));
635    
636    
637     // Now calculate UDP packet checksum in NIC RAM -- should match pseudoHeader
638     IPSetRxBuffer(0);
639     checksums.w[1] = CalcIPBufferChecksum(len);
640    
641     if(checksums.w[0] != checksums.w[1])
642     {
643     MACDiscardRx();
644     return TRUE;
645     }
646     }
647    
648     s = FindMatchingSocket(&h, remoteNode, localIP);
649     if ( s == INVALID_UDP_SOCKET )
650     {
651     // If there is no matching socket, There is no one to handle
652     // this data. Discard it.
653     MACDiscardRx();
654     }
655     else
656     {
657     UDPSocketInfo[s].RxCount = h.Length;
658     UDPSocketInfo[s].Flags.bFirstRead = TRUE;
659     }
660    
661    
662     return TRUE;
663     }
664    
665    
666     /*********************************************************************
667     * Function: UDP_SOCKET FindMatchingSocket(UDP_HEADER *h,
668     * NODE_INFO *remoteNode,
669     * IP_ADDR *localIP)
670     *
671     * PreCondition: UDP Segment header has been retrieved from buffer
672     * The IP header has also been retrieved
673     *
674     * Input: remoteNode - Remote node info from IP header
675     * h - header of UDP semgent.
676     *
677     * Output: matching UDP socket or INVALID_UDP_SOCKET
678     *
679     * Side Effects: None
680     *
681     * Overview: None
682     *
683     * Note: None
684     ********************************************************************/
685     #define BROADCAST_ADDRESS (0xfffffffful)
686     static UDP_SOCKET FindMatchingSocket(UDP_HEADER *h,
687     NODE_INFO *remoteNode,
688     IP_ADDR *localIP)
689     {
690     UDP_SOCKET s;
691     UDP_SOCKET partialMatch;
692     UDP_SOCKET_INFO *p;
693    
694     partialMatch = INVALID_UDP_SOCKET;
695    
696     p = UDPSocketInfo;
697     for ( s = 0; s < MAX_UDP_SOCKETS; s++ )
698     {
699     // This packet is said to be matching with current socket
700     // 1. If its destination port matches with our local port.
701     // 2. This socket does not have any data pending.
702     // 3. Packet source IP address matches with socket remote IP address.
703     // OR this socket had transmitted packet with destination address as broadcast.
704     if ( p->localPort == h->DestinationPort )
705     {
706     if ( (p->remotePort == h->SourcePort) && (p->RxCount == 0ul) )
707     {
708     if ( (p->remoteNode.IPAddr.Val == remoteNode->IPAddr.Val) ||
709     (localIP->Val == BROADCAST_ADDRESS) )
710     {
711     return s;
712     }
713     }
714    
715     partialMatch = s;
716     }
717     p++;
718     }
719    
720     if ( partialMatch != INVALID_UDP_SOCKET )
721     {
722     p = &UDPSocketInfo[partialMatch];
723    
724     memcpy((void*)&p->remoteNode,
725     (const void*)remoteNode, sizeof(p->remoteNode) );
726    
727     p->remotePort = h->SourcePort;
728     }
729     return partialMatch;
730     }
731    
732    
733     #endif //#if defined(STACK_USE_UDP)

  ViewVC Help
Powered by ViewVC 1.1.20