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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 15 - (show 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 /*********************************************************************
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