📄 funcudp.c
字号:
/********************************************************************
* Name : funcudp.c
* Author : Chang J.
* Description :
* This file contains some functions to operate the UDP socket. For
* the reason that we post UDP data directly to the application task,
* no Read() or Rcvfrom() function applied.
* History :
* 2003.05.15 begin test
*******************************************************************/
#include "includes.h"
#include "network.h"
#include "funcudp.h"
#include "ppp.h"
extern OS_MEM *pMemHug;
//extern INT8U rom IPAddress[4];
//extern INT8U rom *PPPMakeHeader(INT8U rom * pBuf, INT16U Protocol);
extern INT8U rom *IPMakeHeader(IP_ADDR remoteAddr,
INT8U rom * pBuf,
INT8U Protocol,
INT16U LenOfPayload);
//extern INT16U swaps(INT16U v);
//extern INT8U PPPSendPacket (INT8U rom *Buffer, INT16U len);
extern INT16U IPCheckSum (INT8U rom * Data, INT16U Size);
#define UDPTX_MCB pMemHug //We use Huge memblock for UDP transmition
#pragma romdata EXTRAM
UDP_SOCKET_INFO UDPSocketInfo[MAX_UDP_SOCKETS];
#pragma code MYCODE
/*********************************************************************
* 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++ ){
UDPSocketInfo[s].localPort = INVALID_UDP_SOCKET;
UDPSocketInfo[s].sockOwner = (OS_EVENT *)NULL_PTR;
UDPSocketInfo[s].TxCount = 0;
}
}
/*********************************************************************
* Function: UDP_SOCKET UDPOpen(IP_ADDR remoteAddr,
* UDP_PORT remotePort,
* UDP_PORT localPort,
* OS_EVENT *sockOwner)
* PreCondition: UDPInit() is already called
* Input: remoteAddr - Remote 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.
* sockOwner - The event ptr where the receiver of the
* socket wait rx data
* Output: A valid UDP socket that is to be used for
* subsequent UDP communications.
* Side Effects: None
* Overview: Do nothing but set certain parameters into an empty
* socket.
* Note: This call must always have valid localPort
* value.
********************************************************************/
UDP_SOCKET UDPOpen(IP_ADDR remoteAddr,
UDP_PORT remotePort,
UDP_PORT localPort,
OS_EVENT * sockOwner){
UDP_SOCKET s;
UDP_SOCKET_INFO *p;
INT8U i;
p = UDPSocketInfo;
for ( s = 0; s < MAX_UDP_SOCKETS; s++ ) {
if ( p->localPort == INVALID_UDP_SOCKET ){
p->remoteAddr.Val = remoteAddr.Val;
p->remotePort = remotePort;
p->localPort = localPort;
p->sockOwner = sockOwner;
p->TxCount = 0;
return s;
}
p++;
}
//If can not find an empty socket ...
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_SOCKET;
UDPSocketInfo[s].sockOwner = (OS_EVENT *)NULL_PTR;
if(UDPSocketInfo[s].TxCount != 0){
OSMemPut(UDPTX_MCB, UDPSocketInfo[s].TxBuf);
UDPSocketInfo[s].TxCount = 0;
}
}
/*********************************************************************
* Function: INT8U UDPPutS(UDP_SOCKET s,INT8U rom * pD, INT16U len)
* PreCondition: UDPOpen() has been called.
* Input: s - Socket the data block shall be put into
* pD - Pointer to data byte to be loaded into
* socket transmit buffer
* len - Length of input data in unit of byte
* Output: TRUE if transmit buffer is enough to hold the data
* FALSE if the socket is invilad or data is too long,
* or can't fetch transmission buffer.
* Side Effects: None
* Overview: Given data block is put into UDP transmit buffer
* and selected UDP socket buffer length is incremented
* If buffer has become full, FALSE is returned.
* Or else TRUE is returned.
* Note: The input data shall be located in the external RAM
********************************************************************/
INT8U UDPPutS(UDP_SOCKET s,
INT8U rom * pD,
INT16U len){
INT8U rom * pT;
INT8U err;
INT16U i;
if(len == 0) return(FALSE);
if(UDPSocketInfo[s].localPort == INVALID_UDP_SOCKET) return(FALSE);
if(UDPSocketInfo[s].TxCount+len > MAX_UDP_DATA) return (FALSE);
if(UDPSocketInfo[s].TxCount == 0){ //If the buffer has not been applied ...
pT = OSMemGet(UDPTX_MCB, &err);
if(err != OS_NO_ERR) return(FALSE);
UDPSocketInfo[s].TxBuf = pT;
}
pT = UDPSocketInfo[s].TxBuf + UDPSocketInfo[s].TxCount
+ PPP_HEADLEN + IP_HEADLEN + UDP_HEADLEN;
for(i=0;i<len;i++){
*pT = *pD;
pT++;
pD++;
}
UDPSocketInfo[s].TxCount += len;
return(TRUE);
}
/*********************************************************************
* Function: INT8U UDPPutB(UDP_SOCKET s,INT8U byte)
* PreCondition: UDPOpen() has been called.
* Input: s - Socket the data block shall be put into
* byte - Data byte to be loaded into socket txbuf
* Output: TRUE if transmit buffer is enough to hold the data
* FALSE if the socket is invilad, data is too long,
* or can not fetch transmission buffer
* Side Effects: None
* Overview: Given data byte is put into selected UDP transmit
* buffer and the UDP socket buffer length is incremented
* If buffer has become full, FALSE is returned.
* Or else TRUE is returned.
* Note: None
********************************************************************/
INT8U UDPPutB(UDP_SOCKET s,INT8U byte){
INT8U err;
INT8U rom * pT;
if(UDPSocketInfo[s].localPort == INVALID_UDP_SOCKET) return(FALSE);
if(UDPSocketInfo[s].TxCount == MAX_UDP_DATA) return (FALSE);
if(UDPSocketInfo[s].TxCount == 0){ //If the buffer has not been applied ...
pT = OSMemGet(UDPTX_MCB, &err);
if(err != OS_NO_ERR) return(FALSE);
UDPSocketInfo[s].TxBuf = pT;
}
pT = UDPSocketInfo[s].TxBuf + UDPSocketInfo[s].TxCount + PPP_HEADLEN + IP_HEADLEN+UDP_HEADLEN;
*pT = byte;
UDPSocketInfo[s].TxCount++;
return(TRUE);
}
/*********************************************************************
* Function: INT8U UDPFlush(UDP_SOCKET s,
* IP_ADDR remoteAddr,
* INT16U remotePort)
* PreCondition: UDPPutS() or UDOPutB() is already called.
* Input: None
* Output: None
* Side Effects: None
* Overview: None
* Note: This function transmit all data from selected
* socket.
********************************************************************/
void UDPFlush(UDP_SOCKET s,
IP_ADDR remoteAddr,
INT16U remotePort){
INT8U rom * pT;
UDP_SOCKET_INFO *p;
p = &UDPSocketInfo[s];
pT = PPPMakeHeader(p->TxBuf, IP); //The PPP header is set, and return the PPP payload address
pT = IPMakeHeader(remoteAddr,pT,UDP, p->TxCount + UDP_HEADLEN); //Set IP header and return the payload address
//Now make the UDP header
((UDP_HEADER *)pT)->SourcePort = swaps(p->localPort);
((UDP_HEADER *)pT)->DestinationPort = swaps(remotePort);
((UDP_HEADER *)pT)->Length = swaps(p->TxCount + 8);
((UDP_HEADER *)pT)->Checksum = 0;
//Calculate the UDP Chksum if want, or just set UDP chksum 0
//temp = UDP_Checksum(p->TxBuf + 4);
//((UDP_HEADER *)pT)->Checksum = swaps(temp);
PPPSendPacket(p->TxBuf, p->TxCount+UDP_HEADLEN+IP_HEADLEN+PPP_HEADLEN);
OSMemPut(UDPTX_MCB, p->TxBuf); //Release the tx buffer
//return TRUE;
}
/*********************************************************************
* Function: UDPClear(UDP_SOCKET s)
* PreCondition: UDPOpen() hass already been called.
* Input: None
* Output: None
* Side Effects: None
* Overview: None
* Note: This function release the tx buffer if the socket
* currently has one.
********************************************************************/
void UDPClear(UDP_SOCKET s){
if(UDPSocketInfo[s].TxCount == 0) return;
OSMemPut(UDPTX_MCB, UDPSocketInfo[s].TxBuf); //Release the tx buffer
UDPSocketInfo[s].TxCount = 0;
}
/*********************************************************************
* We can use following code in UDP data process routine :
//process data--we just copy data and send it back for test
UDPPutS(TstSock, ((MSG_UDP *)pSml)-> pPayload, ((MSG_UDP *)pSml)-> LenOfPayload);
//and we can put some other data like
UDPPutB(TstSock, 0x88);
UDPPutB(TstSock, 0xce);
DestAddr.Val = IPGetSrcAddress(((MSG_HEAD *)pMsg)->pMem);
SrcAddr.Val = IPGetDestAddress(((MSG_HEAD *)pMsg)->pMem);
DestPort = ((MSG_UDP *)pMsg)->SourcePort;
UDPFlush(TstSock, DestAddr, DestPort);
//Finished
********************************************************************/
INT16U UDP_Checksum (INT8U rom * pip) { //"pip" point to head of current tx ip packet
INT32U Checksum;
INT16U len;
Checksum = 0;
len = pip[24];
len = len << 8;
len += pip[25];
if((len & 1) != 0){ //the length is odd
len++;
pip[len+20] = 0; //add a padding byte "0" to calculate the chksum, it need whole words
}
Checksum = IPCheckSum (&pip[12], (8 + len) >> 1); //chksum of arc, dest address and all the field in UDP
Checksum = ~Checksum + UDP;
Checksum += pip [25]; //the length domain
Checksum = (Checksum >> 16) + (Checksum & 0xFFFF);
Checksum += (Checksum >> 16);
return (WORD)~Checksum;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -