?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 32

Line No. Rev Author Line
1 32 kaklik /*********************************************************************
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: IP, Ethernet (ENC28J60.c or ETH97J60.c)
12 * Processor: PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F, PIC32
13 * Compiler: Microchip C32 v1.05 or higher
14 * Microchip C30 v3.12 or higher
15 * Microchip C18 v3.30 or higher
16 * HI-TECH PICC-18 PRO 9.63PL2 or higher
17 * Company: Microchip Technology, Inc.
18 *
19 * Software License Agreement
20 *
21 * Copyright (C) 2002-2009 Microchip Technology Inc. All rights
22 * reserved.
23 *
24 * Microchip licenses to you the right to use, modify, copy, and
25 * distribute:
26 * (i) the Software when embedded on a Microchip microcontroller or
27 * digital signal controller product ("Device") which is
28 * integrated into Licensee's product; or
29 * (ii) ONLY the Software driver source files ENC28J60.c, ENC28J60.h,
30 * ENCX24J600.c and ENCX24J600.h ported to a non-Microchip device
31 * used in conjunction with a Microchip ethernet controller for
32 * the sole purpose of interfacing with the ethernet controller.
33 *
34 * You should refer to the license agreement accompanying this
35 * Software for additional information regarding your rights and
36 * obligations.
37 *
38 * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
39 * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
40 * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
41 * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
42 * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR
43 * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
44 * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
45 * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
46 * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
47 * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
48 * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
49 *
50 *
51 * Author Date Comment
52 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
53 * Nilesh Rajbharti 3/19/01 Original (Rev 1.0)
54 * Nilesh Rajbharti 2/26/03 Fixed UDPGet and UDPProcess bugs
55 * as discovered and fixed by John Owen
56 * of Powerwave.
57 * 1. UDPGet would return FALSE on last good byte
58 * 2. UDPProcess was incorrectly calculating length.
59 * Nilesh Rajbharti 5/19/03 Added bFirstRead flag similar to TCP
60 * to detect very first UDPGet and
61 * reset MAC Rx pointer to begining of
62 * UDP data area. This would ensure that
63 * if UDP socket has pending Rx data and
64 * another module resets MAC Rx pointer,
65 * next UDP socket Get would get correct
66 * data.
67 * Robert Sloan (RSS) 5/29/03 Improved FindMatchingSocket()
68 * Nilesh Rajbharti 12/2/03 Added UDPChecksum logic in UDPProcess()
69 * Nilesh Rajbharti 12/5/03 Modified UDPProcess() and FindMatchingSocket()
70 * to include localIP as new parameter.
71 * This corrects pseudo header checksum
72 * logic in UDPProcess().
73 * It also corrects broadcast packet
74 * matching correct in FindMatchingSocket().
75 * Howard Schlunder 1/16/06 Fixed an imporbable RX checksum bug
76 * when using a Microchip Ethernet controller)
77 * Howard Schlunder 6/02/06 Fixed a bug where all RXed UDP packets
78 * without a checksum (0x0000) were thrown
79 * away. No checksum is legal in UDP.
80 * Howard Schlunder 8/10/06 Fixed a bug where UDP sockets would
81 * unintentionally keep the remote MAC
82 * address cached, even after calling
83 * UDPInit(), UDPClose(), or reseting
84 * the part without clearing all the
85 * PIC memory.
86 ********************************************************************/
87 #define __UDP_C
88  
89 #include "TCPIP Stack/TCPIP.h"
90  
91 #if defined(STACK_USE_UDP)
92  
93 /****************************************************************************
94 Section:
95 Configuration Parameters
96 ***************************************************************************/
97  
98 // First port number for randomized local port number selection
99 #define LOCAL_UDP_PORT_START_NUMBER (4096u)
100  
101 // Last port number for randomized local port number selection
102 #define LOCAL_UDP_PORT_END_NUMBER (8192u)
103  
104 /****************************************************************************
105 Section:
106 UDP Global Variables
107 ***************************************************************************/
108  
109 // Stores an array of information pertaining to each UDP socket
110 UDP_SOCKET_INFO UDPSocketInfo[MAX_UDP_SOCKETS];
111  
112 // Indicates which UDP socket is currently active
113 UDP_SOCKET activeUDPSocket;
114  
115 WORD UDPTxCount; // Number of bytes written to this UDP segment
116 WORD UDPRxCount; // Number of bytes read from this UDP segment
117 static UDP_SOCKET LastPutSocket = INVALID_UDP_SOCKET; // Indicates the last socket to which data was written
118 static WORD wPutOffset; // Offset from beginning of payload where data is to be written.
119 static WORD wGetOffset; // Offset from beginning of payload from where data is to be read.
120  
121 // Stores various flags for the UDP module
122 static struct
123 {
124 unsigned char bFirstRead : 1; // No data has been read from this segment yet
125 unsigned char bWasDiscarded : 1; // The data in this segment has been discarded
126 } Flags;
127  
128 // Indicates which socket has currently received data for this loop
129 static UDP_SOCKET SocketWithRxData = INVALID_UDP_SOCKET;
130  
131 /****************************************************************************
132 Section:
133 Function Prototypes
134 ***************************************************************************/
135  
136 static UDP_SOCKET FindMatchingSocket(UDP_HEADER *h, NODE_INFO *remoteNode,
137 IP_ADDR *localIP);
138  
139 /****************************************************************************
140 Section:
141 Connection Management Functions
142 ***************************************************************************/
143  
144 /*****************************************************************************
145 Function:
146 void UDPInit(void)
147  
148 Summary:
149 Initializes the UDP module.
150  
151 Description:
152 Initializes the UDP module. This function initializes all the UDP
153 sockets to the closed state.
154  
155 Precondition:
156 None
157  
158 Parameters:
159 None
160  
161 Returns:
162 None
163  
164 Remarks:
165 This function is called only one during lifetime of the application.
166 ***************************************************************************/
167 void UDPInit(void)
168 {
169 UDP_SOCKET s;
170  
171 for ( s = 0; s < MAX_UDP_SOCKETS; s++ )
172 {
173 UDPClose(s);
174 }
175 Flags.bWasDiscarded = 1;
176 }
177  
178  
179 /*****************************************************************************
180 Function:
181 void UDPTask(void)
182  
183 Summary:
184 Performs state management and housekeeping for UDP.
185  
186 Description:
187 Performs state management and housekeeping for UDP. This is an internal
188 function meant to be called by StackTask() (not a user API).
189  
190 Precondition:
191 None
192  
193 Parameters:
194 None
195  
196 Return Values:
197 None
198  
199 Remarks:
200 UDPTask() is called once per StackTask() iteration to ensure that calls
201 to UDPIsPutReady() always update the Ethernet Write pointer location
202 between StackTask() iterations.
203 ***************************************************************************/
204 void UDPTask(void)
205 {
206 LastPutSocket = INVALID_UDP_SOCKET;
207 }
208  
209  
210 /*****************************************************************************
211 Function:
212 UDP_SOCKET UDPOpen(UDP_PORT localPort, NODE_INFO* remoteNode,
213 UDP_PORT remotePort)
214  
215 Summary:
216 Creates a UDP socket handle for transmiting or receiving UDP packets.
217  
218 Description:
219 Creates a UDP socket handle for transmiting or receiving UDP packets.
220 Call this function to obtain a handle required by other UDP function.
221  
222 Precondition:
223 UDPInit() must have been previously called.
224  
225 Parameters:
226 localPort - UDP port number to listen on. If 0, stack will dynamically
227 assign a unique port number to use.
228 remoteNode - Pointer to remote node info (MAC and IP address) for this
229 connection. If this is a server socket (receives the first packet)
230 or the destination is the broadcast address, then this parameter
231 should be NULL.
232 remotePort - For client sockets, the remote port number.
233  
234 Return Values:
235 Success -
236 A UDP socket handle that can be used for subsequent UDP API calls.
237 Failure -
238 INVALID_UDP_SOCKET. This function fails when no more UDP socket
239 handles are available. Increase MAX_UDP_SOCKETS to make more sockets
240 available.
241  
242 Remarks:
243 When finished using the UDP socket handle, call the UDPClose() function
244 to free the socket and delete the handle.
245 ***************************************************************************/
246 UDP_SOCKET UDPOpen(UDP_PORT localPort,
247 NODE_INFO *remoteNode,
248 UDP_PORT remotePort)
249 {
250 UDP_SOCKET s;
251 UDP_SOCKET_INFO *p;
252  
253 // Local temp port numbers.
254 static WORD NextPort __attribute__((persistent));
255  
256  
257 p = UDPSocketInfo;
258 for ( s = 0; s < MAX_UDP_SOCKETS; s++ )
259 {
260 if(p->localPort == INVALID_UDP_PORT)
261 {
262 p->localPort = localPort;
263  
264 if(localPort == 0x0000u)
265 {
266 if(NextPort > LOCAL_UDP_PORT_END_NUMBER || NextPort < LOCAL_UDP_PORT_START_NUMBER)
267 NextPort = LOCAL_UDP_PORT_START_NUMBER;
268  
269 p->localPort = NextPort++;
270 }
271  
272 // If remoteNode is supplied, remember it.
273 if(remoteNode)
274 {
275 memcpy((void*)&p->remoteNode,
276 (const void*)remoteNode,
277 sizeof(p->remoteNode));
278 }
279 else
280 {
281 // else Set broadcast address
282 memset((void*)&p->remoteNode, 0xFF, sizeof(p->remoteNode));
283 }
284  
285 p->remotePort = remotePort;
286  
287 // Mark this socket as active.
288 // Once an active socket is set, subsequent operation can be
289 // done without explicitely supply socket identifier.
290 activeUDPSocket = s;
291 return s;
292 }
293 p++;
294 }
295  
296 return (UDP_SOCKET)INVALID_UDP_SOCKET;
297 }
298  
299  
300  
301  
302 /*****************************************************************************
303 Function:
304 void UDPClose(UDP_SOCKET s)
305  
306 Summary:
307 Closes a UDP socket and frees the handle.
308  
309 Description:
310 Closes a UDP socket and frees the handle. Call this function to release
311 a socket and return it to the pool for use by future communications.
312  
313 Precondition:
314 UDPInit() must have been previously called.
315  
316 Parameters:
317 s - The socket handle to be released. If an illegal handle value is
318 provided, the function safely does nothing.
319  
320 Returns:
321 None
322  
323 Remarks:
324 This function does not affect the previously designated active socket.
325 ***************************************************************************/
326 void UDPClose(UDP_SOCKET s)
327 {
328 if(s >= MAX_UDP_SOCKETS)
329 return;
330  
331 UDPSocketInfo[s].localPort = INVALID_UDP_PORT;
332 UDPSocketInfo[s].remoteNode.IPAddr.Val = 0x00000000;
333 }
334  
335  
336 /*****************************************************************************
337 Function:
338 void UDPSetTxBuffer(WORD wOffset)
339  
340 Summary:
341 Moves the pointer within the TX buffer.
342  
343 Description:
344 This function allows the write location within the TX buffer to be
345 specified. Future calls to UDPPut, UDPPutArray, UDPPutString, etc will
346 write data from the indicated location.
347  
348 Precondition:
349 UDPInit() must have been previously called and a socket is currently
350 active.
351  
352 Parameters:
353 wOffset - Offset from beginning of UDP packet data payload to place the
354 write pointer.
355  
356 Returns:
357 None
358 ***************************************************************************/
359 void UDPSetTxBuffer(WORD wOffset)
360 {
361 IPSetTxBuffer(wOffset+sizeof(UDP_HEADER));
362 wPutOffset = wOffset;
363 }
364  
365  
366 /*****************************************************************************
367 Function:
368 void UDPSetRxBuffer(WORD wOffset)
369  
370 Summary:
371 Moves the pointer within the RX buffer.
372  
373 Description:
374 This function allows the read location within the RX buffer to be
375 specified. Future calls to UDPGet and UDPGetArray will read data from
376 the indicated location forward.
377  
378 Precondition:
379 UDPInit() must have been previously called and a socket is currently
380 active.
381  
382 Parameters:
383 wOffset - Offset from beginning of UDP packet data payload to place the
384 read pointer.
385  
386 Returns:
387 None
388 ***************************************************************************/
389 void UDPSetRxBuffer(WORD wOffset)
390 {
391 IPSetRxBuffer(wOffset+sizeof(UDP_HEADER));
392 wGetOffset = wOffset;
393 }
394  
395  
396  
397 /****************************************************************************
398 Section:
399 Transmit Functions
400 ***************************************************************************/
401  
402 /*****************************************************************************
403 Function:
404 WORD UDPIsPutReady(UDP_SOCKET s)
405  
406 Summary:
407 Determines how many bytes can be written to the UDP socket.
408  
409 Description:
410 This function determines if bytes can be written to the specified UDP
411 socket. It also prepares the UDP module for writing by setting the
412 indicated socket as the currently active connection.
413  
414 Precondition:
415 UDPInit() must have been previously called.
416  
417 Parameters:
418 s - The socket to be made active
419  
420 Returns:
421 The number of bytes that can be written to this socket.
422 ***************************************************************************/
423 WORD UDPIsPutReady(UDP_SOCKET s)
424 {
425 if(!MACIsTxReady())
426 return 0;
427  
428 if(LastPutSocket != s)
429 {
430 LastPutSocket = s;
431 UDPTxCount = 0;
432 UDPSetTxBuffer(0);
433 }
434  
435 activeUDPSocket = s;
436  
437 return MAC_TX_BUFFER_SIZE - sizeof(IP_HEADER) - sizeof(UDP_HEADER) - UDPTxCount;
438 }
439  
440 /*****************************************************************************
441 Function:
442 BOOL UDPPut(BYTE v)
443  
444 Summary:
445 Writes a byte to the currently active socket.
446  
447 Description:
448 This function writes a single byte to the currently active UDP socket,
449 while incrementing the buffer length. UDPIsPutReady should be used
450 before calling this function to specify the currently active socket.
451  
452 Precondition:
453 UDPIsPutReady() was previously called to specify the current socket.
454  
455 Parameters:
456 v - The byte to be loaded into the transmit buffer.
457  
458 Return Values:
459 TRUE - The byte was successfully written to the socket.
460 FALSE - The transmit buffer is already full and so the write failed.
461 ***************************************************************************/
462 BOOL UDPPut(BYTE v)
463 {
464 // See if we are out of transmit space.
465 if(wPutOffset >= (MAC_TX_BUFFER_SIZE - sizeof(IP_HEADER) - sizeof(UDP_HEADER)))
466 {
467 return FALSE;
468 }
469  
470 // Load application data byte
471 MACPut(v);
472 wPutOffset++;
473 if(wPutOffset > UDPTxCount)
474 UDPTxCount = wPutOffset;
475  
476 return TRUE;
477 }
478  
479 /*****************************************************************************
480 Function:
481 WORD UDPPutArray(BYTE *cData, WORD wDataLen)
482  
483 Summary:
484 Writes an array of bytes to the currently active socket.
485  
486 Description:
487 This function writes an array of bytes to the currently active UDP socket,
488 while incrementing the buffer length. UDPIsPutReady should be used
489 before calling this function to specify the currently active socket.
490  
491 Precondition:
492 UDPIsPutReady() was previously called to specify the current socket.
493  
494 Parameters:
495 cData - The array to write to the socket.
496 wDateLen - Number of bytes from cData to be written.
497  
498 Returns:
499 The number of bytes successfully placed in the UDP transmit buffer. If
500 this value is less than wDataLen, then the buffer became full and the
501 input was truncated.
502 ***************************************************************************/
503 WORD UDPPutArray(BYTE *cData, WORD wDataLen)
504 {
505 WORD wTemp;
506  
507 wTemp = (MAC_TX_BUFFER_SIZE - sizeof(IP_HEADER) - sizeof(UDP_HEADER)) - wPutOffset;
508 if(wTemp < wDataLen)
509 wDataLen = wTemp;
510  
511 wPutOffset += wDataLen;
512 if(wPutOffset > UDPTxCount)
513 UDPTxCount = wPutOffset;
514  
515 // Load application data bytes
516 MACPutArray(cData, wDataLen);
517  
518 return wDataLen;
519 }
520  
521 /*****************************************************************************
522 Function:
523 WORD UDPPutROMArray(ROM BYTE *cData, WORD wDataLen)
524  
525 Summary:
526 Writes an array of bytes from ROM to the currently active socket.
527  
528 Description:
529 This function writes an array of bytes from ROM to the currently active
530 UDP socket, while incrementing the buffer length. UDPIsPutReady should
531 be used before calling this function to specify the currently active
532 socket.
533  
534 Precondition:
535 UDPIsPutReady() was previously called to specify the current socket.
536  
537 Parameters:
538 cData - The array to write to the socket.
539 wDateLen - Number of bytes from cData to be written.
540  
541 Returns:
542 The number of bytes successfully placed in the UDP transmit buffer. If
543 this value is less than wDataLen, then the buffer became full and the
544 input was truncated.
545  
546 Remarks:
547 This function is aliased to UDPPutArray on non-PIC18 platforms.
548 ***************************************************************************/
549 #if defined(__18CXX)
550 WORD UDPPutROMArray(ROM BYTE *cData, WORD wDataLen)
551 {
552 WORD wTemp;
553  
554 wTemp = (MAC_TX_BUFFER_SIZE - sizeof(IP_HEADER) - sizeof(UDP_HEADER)) - wPutOffset;
555 if(wTemp < wDataLen)
556 wDataLen = wTemp;
557  
558 wPutOffset += wDataLen;
559 if(wPutOffset > UDPTxCount)
560 UDPTxCount = wPutOffset;
561  
562 // Load application data bytes
563 MACPutROMArray(cData, wDataLen);
564  
565 return wDataLen;
566 }
567 #endif
568  
569 /*****************************************************************************
570 Function:
571 BYTE* UDPPutString(BYTE *strData)
572  
573 Summary:
574 Writes null-terminated string to the currently active socket.
575  
576 Description:
577 This function writes a null-terminated string to the currently active
578 UDP socket, while incrementing the buffer length. UDPIsPutReady should
579 be used before calling this function to specify the currently active
580 socket.
581  
582 Precondition:
583 UDPIsPutReady() was previously called to specify the current socket.
584  
585 Parameters:
586 cData - Pointer to the string to be written to the socket.
587  
588 Returns:
589 A pointer to the byte following the last byte written. Note that this
590 is different than the UDPPutArray functions. If this pointer does not
591 dereference to a NULL byte, then the buffer became full and the input
592 data was truncated.
593 ***************************************************************************/
594 BYTE* UDPPutString(BYTE *strData)
595 {
596 return strData + UDPPutArray(strData, strlen((char*)strData));
597 }
598  
599 /*****************************************************************************
600 Function:
601 BYTE* UDPPutString(BYTE *strData)
602  
603 Summary:
604 Writes null-terminated string from ROM to the currently active socket.
605  
606 Description:
607 This function writes a null-terminated string from ROM to the currently
608 active UDP socket, while incrementing the buffer length. UDPIsPutReady
609 should be used before calling this function to specify the currently
610 active socket.
611  
612 Precondition:
613 UDPIsPutReady() was previously called to specify the current socket.
614  
615 Parameters:
616 cData - Pointer to the string to be written to the socket.
617  
618 Returns:
619 A pointer to the byte following the last byte written. Note that this
620 is different than the UDPPutArray functions. If this pointer does not
621 dereference to a NULL byte, then the buffer became full and the input
622 data was truncated.
623  
624 Remarks:
625 This function is aliased to UDPPutString on non-PIC18 platforms.
626 ***************************************************************************/
627 #if defined(__18CXX)
628 ROM BYTE* UDPPutROMString(ROM BYTE *strData)
629 {
630 return strData + UDPPutROMArray(strData, strlenpgm((ROM char*)strData));
631 }
632 #endif
633  
634 /*****************************************************************************
635 Function:
636 void UDPFlush(void)
637  
638 Summary:
639 Transmits all pending data in a UDP socket.
640  
641 Description:
642 This function builds a UDP packet with the pending TX data and marks it
643 for transmission over the network interface. Since UDP is a frame-based
644 protocol, this function must be called before returning to the main
645 stack loop whenever any data is written.
646  
647 Precondition:
648 UDPIsPutReady() was previously called to specify the current socket, and
649 data has been written to the socket using the UDPPut family of functions.
650  
651 Parameters:
652 None
653  
654 Returns:
655 None
656  
657 Remarks:
658 Note that unlike TCPFlush, UDPFlush must be called before returning to
659 the main stack loop. There is no auto transmit for UDP segments.
660 ***************************************************************************/
661 void UDPFlush(void)
662 {
663 UDP_HEADER h;
664 UDP_SOCKET_INFO *p;
665 WORD wUDPLength;
666  
667 p = &UDPSocketInfo[activeUDPSocket];
668  
669 wUDPLength = UDPTxCount + sizeof(UDP_HEADER);
670  
671 // Generate the correct UDP header
672 h.SourcePort = swaps(p->localPort);
673 h.DestinationPort = swaps(p->remotePort);
674 h.Length = swaps(wUDPLength);
675 h.Checksum = 0x0000;
676  
677 // Calculate IP pseudoheader checksum if we are going to enable
678 // the checksum field
679 #if defined(UDP_USE_TX_CHECKSUM)
680 {
681 PSEUDO_HEADER pseudoHeader;
682  
683 pseudoHeader.SourceAddress = AppConfig.MyIPAddr;
684 pseudoHeader.DestAddress = p->remoteNode.IPAddr;
685 pseudoHeader.Zero = 0x0;
686 pseudoHeader.Protocol = IP_PROT_UDP;
687 pseudoHeader.Length = wUDPLength;
688 SwapPseudoHeader(pseudoHeader);
689 h.Checksum = ~CalcIPChecksum((BYTE*)&pseudoHeader, sizeof(pseudoHeader));
690 }
691 #endif
692  
693 // Position the hardware write pointer where we will need to
694 // begin writing the IP header
695 MACSetWritePtr(BASE_TX_ADDR + sizeof(ETHER_HEADER));
696  
697 // Write IP header to packet
698 IPPutHeader(&p->remoteNode, IP_PROT_UDP, wUDPLength);
699  
700 // Write UDP header to packet
701 MACPutArray((BYTE*)&h, sizeof(h));
702  
703 // Calculate the final UDP checksum and write it in, if enabled
704 #if defined(UDP_USE_TX_CHECKSUM)
705 {
706 PTR_BASE wReadPtrSave;
707 WORD wChecksum;
708  
709 wReadPtrSave = MACSetReadPtr(BASE_TX_ADDR + sizeof(ETHER_HEADER) + sizeof(IP_HEADER));
710 wChecksum = CalcIPBufferChecksum(wUDPLength);
711 if(wChecksum == 0x0000u)
712 wChecksum = 0xFFFF;
713 MACSetReadPtr(wReadPtrSave);
714 MACSetWritePtr(BASE_TX_ADDR + sizeof(ETHER_HEADER) + sizeof(IP_HEADER) + 6); // 6 is the offset to the Checksum field in UDP_HEADER
715 MACPutArray((BYTE*)&wChecksum, sizeof(wChecksum));
716 }
717 #endif
718  
719 // Transmit the packet
720 MACFlush();
721  
722 // Reset packet size counter for the next TX operation
723 UDPTxCount = 0;
724 LastPutSocket = INVALID_UDP_SOCKET;
725 }
726  
727  
728  
729 /****************************************************************************
730 Section:
731 Receive Functions
732 ***************************************************************************/
733  
734 /*****************************************************************************
735 Function:
736 WORD UDPIsGetReady(UDP_SOCKET s)
737  
738 Summary:
739 Determines how many bytes can be read from the UDP socket.
740  
741 Description:
742 This function determines if bytes can be read from the specified UDP
743 socket. It also prepares the UDP module for reading by setting the
744 indicated socket as the currently active connection.
745  
746 Precondition:
747 UDPInit() must have been previously called.
748  
749 Parameters:
750 s - The socket to be made active (which has already been opened or is
751 listening)
752  
753 Returns:
754 The number of bytes that can be read from this socket.
755 ***************************************************************************/
756 WORD UDPIsGetReady(UDP_SOCKET s)
757 {
758 activeUDPSocket = s;
759 if(SocketWithRxData != s)
760 return 0;
761  
762 // If this is the very first time we are accessing this packet,
763 // move the read point to the begining of the packet.
764 if(Flags.bFirstRead)
765 {
766 Flags.bFirstRead = 0;
767 UDPSetRxBuffer(0);
768 }
769  
770 return UDPRxCount - wGetOffset;
771 }
772  
773 /*****************************************************************************
774 Function:
775 BOOL UDPGet(BYTE *v)
776  
777 Summary:
778 Reads a byte from the currently active socket.
779  
780 Description:
781 This function reads a single byte from the currently active UDP socket,
782 while decrementing the remaining buffer length. UDPIsGetReady should be
783 used before calling this function to specify the currently active socket.
784  
785 Precondition:
786 UDPIsGetReady() was previously called to specify the current socket.
787  
788 Parameters:
789 v - The buffer to receive the data being read.
790  
791 Return Values:
792 TRUE - A byte was successfully read
793 FALSE - No data remained in the read buffer
794 ***************************************************************************/
795 BOOL UDPGet(BYTE *v)
796 {
797 // Make sure that there is data to return
798 if((wGetOffset >= UDPRxCount) || (SocketWithRxData != activeUDPSocket))
799 return FALSE;
800  
801 *v = MACGet();
802 wGetOffset++;
803  
804 return TRUE;
805 }
806  
807  
808 /*****************************************************************************
809 Function:
810 WORD UDPGetArray(BYTE *cData, WORD wDataLen)
811  
812 Summary:
813 Reads an array of bytes from the currently active socket.
814  
815 Description:
816 This function reads an array of bytes from the currently active UDP socket,
817 while decrementing the remaining bytes available. UDPIsGetReady should be
818 used before calling this function to specify the currently active socket.
819  
820 Precondition:
821 UDPIsGetReady() was previously called to specify the current socket.
822  
823 Parameters:
824 cData - The buffer to receive the bytes being read.
825 wDateLen - Number of bytes to be read from the socket.
826  
827 Returns:
828 The number of bytes successfully read from the UDP buffer. If this
829 value is less than wDataLen, then the buffer was emptied and no more
830 data is available.
831 ***************************************************************************/
832 WORD UDPGetArray(BYTE *cData, WORD wDataLen)
833 {
834 WORD wBytesAvailable;
835  
836 // Make sure that there is data to return
837 if((wGetOffset >= UDPRxCount) || (SocketWithRxData != activeUDPSocket))
838 return 0;
839  
840 // Make sure we don't try to read more data than exists
841 wBytesAvailable = UDPRxCount - wGetOffset;
842 if(wBytesAvailable < wDataLen)
843 wDataLen = wBytesAvailable;
844  
845 wDataLen = MACGetArray(cData, wDataLen);
846 wGetOffset += wDataLen;
847  
848 return wDataLen;
849 }
850  
851 /*****************************************************************************
852 Function:
853 void UDPDiscard(void)
854  
855 Summary:
856 Discards any remaining RX data from a UDP socket.
857  
858 Description:
859 This function discards any remaining received data in the currently
860 active UDP socket.
861  
862 Precondition:
863 UDPIsGetReady() was previously called to select the currently active
864 socket.
865  
866 Parameters:
867 None
868  
869 Returns:
870 None
871  
872 Remarks:
873 It is safe to call this function more than is necessary. If no data is
874 available, this function does nothing.
875 ***************************************************************************/
876 void UDPDiscard(void)
877 {
878 if(!Flags.bWasDiscarded)
879 {
880 MACDiscardRx();
881 UDPRxCount = 0;
882 SocketWithRxData = INVALID_UDP_SOCKET;
883 Flags.bWasDiscarded = 1;
884 }
885 }
886  
887  
888  
889 /****************************************************************************
890 Section:
891 Data Processing Functions
892 ***************************************************************************/
893  
894 /*****************************************************************************
895 Function:
896 BOOL UDPProcess(NODE_INFO *remoteNode, IP_ADDR *localIP, WORD len)
897  
898 Summary:
899 Handles an incoming UDP segment.
900  
901 Description:
902 This function handles an incoming UDP segment to determine if it is
903 acceptable and should be handed to one of the stack applications for
904 processing.
905  
906 Precondition:
907 UDPInit() has been called an a UDP segment is ready in the MAC buffer.
908  
909 Parameters:
910 remoteNode - The remote node that sent this segment.
911 localIP - The destination IP address for this segment.
912 len - Total length of the UDP segment.
913  
914 Return Values:
915 TRUE - A valid packet is waiting and the stack applications should be
916 called to handle it.
917 FALSE - The packet was discarded.
918 ***************************************************************************/
919 BOOL UDPProcess(NODE_INFO *remoteNode, IP_ADDR *localIP, WORD len)
920 {
921 UDP_HEADER h;
922 UDP_SOCKET s;
923 PSEUDO_HEADER pseudoHeader;
924 DWORD_VAL checksums;
925  
926 UDPRxCount = 0;
927  
928 // Retrieve UDP header.
929 MACGetArray((BYTE*)&h, sizeof(h));
930  
931 h.SourcePort = swaps(h.SourcePort);
932 h.DestinationPort = swaps(h.DestinationPort);
933 h.Length = swaps(h.Length) - sizeof(UDP_HEADER);
934  
935 // See if we need to validate the checksum field (0x0000 is disabled)
936 if(h.Checksum)
937 {
938 // Calculate IP pseudoheader checksum.
939 pseudoHeader.SourceAddress = remoteNode->IPAddr;
940 pseudoHeader.DestAddress.Val = localIP->Val;
941 pseudoHeader.Zero = 0x0;
942 pseudoHeader.Protocol = IP_PROT_UDP;
943 pseudoHeader.Length = len;
944  
945 SwapPseudoHeader(pseudoHeader);
946  
947 checksums.w[0] = ~CalcIPChecksum((BYTE*)&pseudoHeader,
948 sizeof(pseudoHeader));
949  
950  
951 // Now calculate UDP packet checksum in NIC RAM -- should match pseudoHeader
952 IPSetRxBuffer(0);
953 checksums.w[1] = CalcIPBufferChecksum(len);
954  
955 if(checksums.w[0] != checksums.w[1])
956 {
957 MACDiscardRx();
958 return FALSE;
959 }
960 }
961  
962 s = FindMatchingSocket(&h, remoteNode, localIP);
963 if(s == INVALID_UDP_SOCKET)
964 {
965 // If there is no matching socket, There is no one to handle
966 // this data. Discard it.
967 MACDiscardRx();
968 return FALSE;
969 }
970 else
971 {
972 SocketWithRxData = s;
973 UDPRxCount = h.Length;
974 Flags.bFirstRead = 1;
975 Flags.bWasDiscarded = 0;
976 }
977  
978  
979 return TRUE;
980 }
981  
982 /*****************************************************************************
983 Function:
984 static UDP_SOCKET FindMatchingSocket(UDP_HEADER *h, NODE_INFO *remoteNode,
985 IP_ADDR *localIP)
986  
987 Summary:
988 Matches an incoming UDP segment to a currently active socket.
989  
990 Description:
991 This function attempts to match an incoming UDP segment to a currently
992 active socket for processing.
993  
994 Precondition:
995 UDP segment header and IP header have both been retrieved.
996  
997 Parameters:
998 h - The UDP header that was received.
999 remoteNode - IP and MAC of the remote node that sent this segment.
1000 localIP - IP address that this segment was destined for.
1001  
1002 Returns:
1003 A UDP_SOCKET handle of a matching socket, or INVALID_UDP_SOCKET when no
1004 match could be made.
1005 ***************************************************************************/
1006 static UDP_SOCKET FindMatchingSocket(UDP_HEADER *h,
1007 NODE_INFO *remoteNode,
1008 IP_ADDR *localIP)
1009 {
1010 UDP_SOCKET s;
1011 UDP_SOCKET partialMatch;
1012 UDP_SOCKET_INFO *p;
1013  
1014 partialMatch = INVALID_UDP_SOCKET;
1015  
1016 p = UDPSocketInfo;
1017 for ( s = 0; s < MAX_UDP_SOCKETS; s++ )
1018 {
1019 // This packet is said to be matching with current socket:
1020 // 1. If its destination port matches with our local port and
1021 // 2. Packet source IP address matches with socket remote IP address.
1022 // OR this socket had transmitted packet with destination address as broadcast (subnet or limited broadcast).
1023 if ( p->localPort == h->DestinationPort )
1024 {
1025 if(p->remotePort == h->SourcePort)
1026 {
1027 if( (p->remoteNode.IPAddr.Val == remoteNode->IPAddr.Val) ||
1028 (localIP->Val == 0xFFFFFFFFul) ||
1029 (localIP->Val == (AppConfig.MyIPAddr.Val | (~AppConfig.MyMask.Val))))
1030 {
1031 return s;
1032 }
1033 #ifdef STACK_USE_ZEROCONF_MDNS_SD
1034 /* Multicast Support in UDP Layer for mDNS.
1035 * mDNS- Multicast DNS for Zeroconf protocol.
1036 * Multicast address used by mDNS: 224.0.0.251 : 5353
1037 * second check with self MAC-address is to
1038 * suppress Loop-Back packets */
1039 else if (localIP->Val == 0xFB0000E0ul)
1040 {
1041 if(remoteNode->IPAddr.Val!= AppConfig.MyIPAddr.Val)
1042 return s;
1043 else
1044 return INVALID_UDP_SOCKET;
1045 }
1046 #endif
1047 }
1048  
1049 partialMatch = s;
1050 }
1051 p++;
1052 }
1053  
1054 if ( partialMatch != INVALID_UDP_SOCKET )
1055 {
1056 p = &UDPSocketInfo[partialMatch];
1057  
1058 memcpy((void*)&p->remoteNode,
1059 (const void*)remoteNode, sizeof(p->remoteNode) );
1060  
1061 p->remotePort = h->SourcePort;
1062 }
1063 return partialMatch;
1064 }
1065  
1066  
1067 #endif //#if defined(STACK_USE_UDP)
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3