📄 udp.c
字号:
/*********************************************************************
*
* UDP Module for Microchip TCP/IP Stack
*
*********************************************************************
* FileName: UDP.c
* Dependencies: StackTsk.h
* MAC.h
* Processor: PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F
* Complier: Microchip C18 v3.02 or higher
* Microchip C30 v2.01 or higher
* Company: Microchip Technology, Inc.
*
* Software License Agreement
*
* This software is owned by Microchip Technology Inc. ("Microchip")
* and is supplied to you for use exclusively as described in the
* associated software agreement. This software is protected by
* software and other intellectual property laws. Any use in
* violation of the software license may subject the user to criminal
* sanctions as well as civil liability. Copyright 2006 Microchip
* Technology Inc. All rights reserved.
*
* This software is provided "AS IS." MICROCHIP DISCLAIMS ALL
* WARRANTIES, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, NOT LIMITED
* TO MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
* INFRINGEMENT. Microchip shall in no event be liable for special,
* incidental, or consequential damages.
*
*
* Author Date Comment
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Nilesh Rajbharti 3/19/01 Original (Rev 1.0)
* Nilesh Rajbharti 2/26/03 Fixed UDPGet and UDPProcess bugs
* as discovered and fixed by John Owen
* of Powerwave.
* 1. UDPGet would return FALSE on last good byte
* 2. UDPProcess was incorrectly calculating length.
* Nilesh Rajbharti 5/19/03 Added bFirstRead flag similar to TCP
* to detect very first UDPGet and
* reset MAC Rx pointer to begining of
* UDP data area. This would ensure that
* if UDP socket has pending Rx data and
* another module resets MAC Rx pointer,
* next UDP socket Get would get correct
* data.
* Robert Sloan (RSS) 5/29/03 Improved FindMatchingSocket()
* Nilesh Rajbharti 12/2/03 Added UDPChecksum logic in UDPProcess()
* Nilesh Rajbharti 12/5/03 Modified UDPProcess() and FindMatchingSocket()
* to include localIP as new parameter.
* This corrects pseudo header checksum
* logic in UDPProcess().
* It also corrects broadcast packet
* matching correct in FindMatchingSocket().
* Howard Schlunder 1/16/06 Fixed an imporbable RX checksum bug
* when using a Microchip Ethernet controller)
* Howard Schlunder 6/02/06 Fixed a bug where all RXed UDP packets
* without a checksum (0x0000) were thrown
* away. No checksum is legal in UDP.
* Howard Schlunder 8/10/06 Fixed a bug where UDP sockets would
* unintentionally keep the remote MAC
* address cached, even after calling
* UDPInit(), UDPClose(), or reseting
* the part without clearing all the
* PICmicro memory.
********************************************************************/
#define THIS_IS_UDP_MODULE
#include <string.h>
#include "..\Include\StackTsk.h"
#include "..\Include\Helpers.h"
#include "..\Include\MAC.h"
#include "..\Include\IP.h"
#include "..\Include\UDP.h"
#if defined(STACK_USE_UDP)
UDP_SOCKET_INFO UDPSocketInfo[MAX_UDP_SOCKETS];
UDP_SOCKET activeUDPSocket;
static UDP_SOCKET FindMatchingSocket(UDP_HEADER *h, NODE_INFO *remoteNode,
IP_ADDR *localIP);
/*********************************************************************
* Function: void UDPInit(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: Initializes internal variables.
*
* Note:
********************************************************************/
void UDPInit(void)
{
UDP_SOCKET s;
for ( s = 0; s < MAX_UDP_SOCKETS; s++ )
{
UDPClose(s);
}
}
/*********************************************************************
* Function: UDP_SOCKET UDPOpen(UDP_PORT localPort,
* NODE_INFO *remoteNode,
* UDP_PORT remotePort)
*
* PreCondition: UDPInit() is already called
*
* Input: remoteNode - Remote Node info such as MAC and IP
* address
* If NULL, broadcast node address is set.
* remotePort - Remote Port to which to talk to
* If INVALID_UDP_SOCKET, localPort is
* opened for Listen.
* localPort - A valid port number.
*
* Output: A valid UDP socket that is to be used for
* subsequent UDP communications.
*
* Side Effects: None
*
* Overview: A UDP packet header is assembled and loaded into
* UDP transmit buffer.
*
* Note: This call must always have valid localPort
* value.
********************************************************************/
UDP_SOCKET UDPOpen(UDP_PORT localPort,
NODE_INFO *remoteNode,
UDP_PORT remotePort)
{
UDP_SOCKET s;
UDP_SOCKET_INFO *p;
p = UDPSocketInfo;
for ( s = 0; s < MAX_UDP_SOCKETS; s++ )
{
if ( p->localPort == INVALID_UDP_PORT )
{
p->localPort = localPort;
// If remoteNode is supplied, remember it.
if ( remoteNode )
{
memcpy((void*)&p->remoteNode,
(const void*)remoteNode,
sizeof(p->remoteNode));
}
// else Set broadcast address - TO BE DONE
p->remotePort = remotePort;
p->TxCount = 0;
p->RxCount = 0;
// Mark this socket as active.
// Once an active socket is set, subsequent operation can be
// done without explicitely supply socket identifier.
activeUDPSocket = s;
return s;
}
p++;
}
return (UDP_SOCKET)INVALID_UDP_SOCKET;
}
/*********************************************************************
* Function: void UDPClose(UDP_SOCKET s)
*
* PreCondition: UDPOpen() is already called
*
* Input: s - Socket that is to be closed.
*
* Output: None
*
* Side Effects: None
*
* Overview: Given socket is marked as available for future
* new communcations.
*
* Note: This function does not affect previous
* active UDP socket designation.
********************************************************************/
void UDPClose(UDP_SOCKET s)
{
UDPSocketInfo[s].localPort = INVALID_UDP_PORT;
UDPSocketInfo[s].remoteNode.IPAddr.Val = 0x00000000;
UDPSocketInfo[s].Flags.bFirstRead = FALSE;
}
/*********************************************************************
* Function: BOOL UDPPut(BYTE v)
*
* PreCondition: UDPIsPutReady() == TRUE with desired UDP socket
* that is to be loaded.
*
* Input: v - Data byte to loaded into transmit buffer
*
* Output: TRUE if transmit buffer is still ready to accept
* more data bytes
*
* FALSE if transmit buffer can no longer accept
* any more data byte.
*
* Side Effects: None
*
* Overview: Given data byte is put into UDP transmit buffer
* and active UDP socket buffer length is incremented
* by one.
* If buffer has become full, FALSE is returned.
* Or else TRUE is returned.
*
* Note: This function loads data into an active UDP socket
* as determined by previous call to UDPIsPutReady()
********************************************************************/
BOOL UDPPut(BYTE v)
{
UDP_SOCKET_INFO *p;
WORD temp;
p = &UDPSocketInfo[activeUDPSocket];
if ( p->TxCount == 0 )
{
// This is the very first byte that is loaded in UDP buffer.
// Remember what transmit buffer we are loading, and
// start loading this and next bytes in data area of UDP packet.
p->TxBuffer = MACGetTxBuffer(TRUE);
// Make sure that we received a TX buffer
if(p->TxBuffer == INVALID_BUFFER)
return FALSE;
IPSetTxBuffer(p->TxBuffer, sizeof(UDP_HEADER));
p->TxOffset = 0;
}
// Load it.
MACPut(v);
// Keep track of number of bytes loaded.
// If total bytes fill up buffer, transmit it.
if ( p->TxOffset++ >= p->TxCount )
p->TxCount++;
#define SIZEOF_MAC_HEADER (14)
// Depending on what communication media is used, allowable UDP
// data length will vary.
#if !defined(STACK_USE_SLIP)
#define MAX_UDP_DATA (MAC_TX_BUFFER_SIZE - SIZEOF_MAC_HEADER - sizeof(IP_HEADER) - sizeof(UDP_HEADER))
#else
#define MAX_UDP_DATA (MAC_TX_BUFFER_SIZE - sizeof(IP_HEADER) - sizeof(UDP_HEADER) )
#endif
temp = p->TxCount;
if ( temp >= MAX_UDP_DATA )
{
UDPFlush();
}
#undef MAX_UDP_DATA
return TRUE;
}
/*********************************************************************
* Function: BOOL UDPFlush(void)
*
* PreCondition: UDPPut() is already called and desired UDP socket
* is set as an active socket by calling
* UDPIsPutReady().
*
* Input: None
*
* Output: All and any data associated with active UDP socket
* buffer is marked as ready for transmission.
*
* Side Effects: None
*
* Overview: None
*
* Note: This function transmit all data from
* an active UDP socket.
********************************************************************/
void UDPFlush(void)
{
UDP_HEADER h;
UDP_SOCKET_INFO *p;
// Wait for TX hardware to become available (finish transmitting
// any previous packet)
while( !IPIsTxReady(TRUE) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -