⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 funcudp.c

📁 本人编写的无线电话程序,给予PIC18C801设计,包括了uCOS的移植以及菜单,自己设计的拼音注入法,完整地一级汉字库,希望对大家有所帮助
💻 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 + -