📄 udp.c
字号:
/******************************************************************
* udp.c: User Datagram Protocol
*
* Copyright (c) 2001 Atmel Corporation.
* All Rights Reserved.
*
* You are autorized to use, copy and distribute this software only at
* a single site (the term "site" meaning a single company location).
* This copyright notice must be included in any copy, modification
* or portion of this software merged into another program.
*
* This software is licenced solely for use with Atmel AVR micro
* controller family. The software may not be modified to execute on
* any other microcontroller architectures
*
* This software is provided "as is"; Without warranties either express
* or implied, including any warranty regarding merchantability,
* fitness for a particular purpose or noninfringement.
*
* In no event shall Atmel or its suppliers be liable for any special,
* indirect,incidential or concequential damages resulting from the
* use or inability to use this software.
*
* Revision history:
*
* January 17, 2001: Version 1.0 Created by JB
* July 13, 2001 Version 1.2 JB
* - Changed to IAR compiler V2.25
* - Renamed flash file functions to avoid conflict with
* standard file I/O names
* - Bug fixes in HTTP
* - Speed optimization in TCP
*
*
*******************************************************************/
#include "udp.h"
#include "ip.h"
#include "main.h"
#include "ethernet.h"
#include <string.h>
#include <stdio.h>
#include <ina90.h>
#include <stdlib.h>
#include "iom103.h"
#define LO(x) ((unsigned char) ((x)&0x00ff)) //returns the lower end byte of an integer
#define HI(x) ((unsigned char) (((x)>>8)&0x00ff)) //returns the higher end byte of an integer
/*flags*/
unsigned char isReading=0; //set to one when data is read from the buffer
unsigned char reading=0; //which buffer is currently being read while isReading=1
unsigned char lastWritten=0; //the last buffer written to by reciveUDP
/*buffers*/
UDPB UDPBuffer[UDP_NUM_BUF]; //udp-buffers for incoming datagrams
extern unsigned int frame[FRAME_SIZE];
extern config_type ID;
/*called by ip-layer when udp datagram is received*/
void receiveUDP(unsigned int UDPStart,unsigned int UDPLength,unsigned int hisIP0,unsigned int hisIP1,unsigned int myIP0,unsigned int myIP1)
{
unsigned int i;
unsigned int *pframe = &frame[UDPStart+UDP_DATA];
unsigned int *pdata = (unsigned int *)UDPBuffer[lastWritten].data;
lastWritten=(lastWritten+1)%UDP_NUM_BUF; //update last written pointer
if (isReading && lastWritten==reading)
{ //if udp is reading from the last written buffer
lastWritten=(lastWritten+1)%UDP_NUM_BUF; //update last written pointer once more
}
if (!(UDP_NUM_BUF==1 && isReading==1)) //cannot write to buffer if size is 1 and app is reading
{
/*add pseudo-header for checksum*/
pframe[UDPStart-6]=hisIP0;
pframe[UDPStart-5]=hisIP1;
pframe[UDPStart-4]=myIP0;
pframe[UDPStart-3]=myIP1;
pframe[UDPStart-2]=17;
pframe[UDPStart-1]=UDPLength;
if (!checksum(&frame[UDPStart-6],UDPLength+UDP_PSEUDO_HEADER_LENGTH) || pframe[UDPStart+UDP_CHECKSUM]==0
|| (pframe[UDPStart+UDP_CHECKSUM]==0xffff && !checksum(&frame[UDPStart-6],UDPLength+UDP_PSEUDO_HEADER_LENGTH)==0) )
{ // cheksum=0, means no valid checksum
/*copy the header into UDPBuffer*/
UDPBuffer[lastWritten].hisIP0=hisIP0;
UDPBuffer[lastWritten].hisIP1=hisIP1;
UDPBuffer[lastWritten].hisPort=pframe[UDPStart+UDP_SENDER_PORT];
UDPBuffer[lastWritten].myPort=pframe[UDPStart+UDP_TARGET_PORT];
UDPBuffer[lastWritten].dataLength=UDPLength-UDP_HEADER_LENGTH;
/*add the data*/
for(i=0;i<(UDPLength-UDP_HEADER_LENGTH)/2;i++)
{
pdata[i] = (LO(pframe[i])<<8) | (HI(pframe[i]));
}
if (UDPLength & 0x0001) //if length is uneven, add the last byte
{
pdata[i-1] = (HI(pframe[i]));
}
}
}
}
/*sends an UDP-datagram*/
unsigned int sendUDP(unsigned char *data, unsigned int dataLength,unsigned int hisIP0,unsigned int hisIP1,unsigned int myPort,unsigned int hisPort)
{
unsigned int i;
unsigned int bytesSent = UDP_MAX_DATA_LENGTH;
unsigned int *pframe = frame;
unsigned int *pdata = (unsigned int *)data;
unsigned char temp;
if (dataLength < bytesSent) //if datalength is too long, bytesSent is set to max
{
bytesSent=dataLength;
}
if (getMAC(hisIP0,hisIP1)) //check if hisIP is in arp-table
{
temp = SREG;
_CLI(); //disable interrupt, to avoid corruption due to an incoming frame
/*add header*/
pframe[UDP_HEADER_START+UDP_SENDER_PORT]=myPort;
pframe[UDP_HEADER_START+UDP_TARGET_PORT]=hisPort;
pframe[UDP_HEADER_START+UDP_LENGTH]=bytesSent+UDP_HEADER_LENGTH;
pframe[UDP_HEADER_START+UDP_CHECKSUM]=0;
/*add data*/
for(i=0;i<bytesSent/2;i++)
{
pframe[UDP_HEADER_START+UDP_DATA+i] = (LO(pdata[i])<<8 | HI(pdata[i]));
}
if (bytesSent & 0x0001) //add one more byte if length is uneven
{
pframe[UDP_HEADER_START+UDP_DATA+i] = LO(pdata[i])<<8;
}
/*add pseudo header for checksum*/
pframe[UDP_HEADER_START-6]=ID.IP0;
pframe[UDP_HEADER_START-5]=ID.IP1;
pframe[UDP_HEADER_START-4]=hisIP0;
pframe[UDP_HEADER_START-3]=hisIP1;
pframe[UDP_HEADER_START-2]=17;
pframe[UDP_HEADER_START-1]=bytesSent+UDP_HEADER_LENGTH;
/*calculate and insert checksum*/
pframe[UDP_HEADER_START+UDP_CHECKSUM]=checksum(&frame[UDP_HEADER_START-6],bytesSent+UDP_HEADER_LENGTH+UDP_PSEUDO_HEADER_LENGTH);
/*pass the datagram down to the ip-layer*/
transmitIP(bytesSent+UDP_HEADER_LENGTH,hisIP0,hisIP1,17);
SREG = temp; //enable interrupt
return 1; //return success
}
else
{
return 0; //remote mac not in arptable, arprequest sent, later retransmission required
}
}
/*polls the udp-buffers*/
unsigned char readUDP(unsigned int port,UDPB * appBuffer)
{
unsigned int i;
unsigned char start; //first buffer to be polled
reading=(lastWritten+1)%UDP_NUM_BUF; //start polling buffer next to the last written
start=reading; //remember which buffer was polled first
do
{
if (UDPBuffer[reading].myPort==port) //is it on the right port
{
isReading=1; //set reading flag to avoid interruption from receiveUDP
if (UDPBuffer[reading].myPort==port) //have to check once more in case receiveUDP started writing,
//just before isReading flag was set
{
/*write data into application buffer*/
appBuffer->hisIP0=UDPBuffer[reading].hisIP0;
appBuffer->hisIP1=UDPBuffer[reading].hisIP1;
appBuffer->hisPort=UDPBuffer[reading].hisPort;
for (i=0;i<UDPBuffer[reading].dataLength;i++)
{
appBuffer->data[i]=UDPBuffer[reading].data[i];
}
appBuffer->dataLength=UDPBuffer[reading].dataLength;
UDPBuffer[reading].myPort=0; //mark buffer as read
isReading=0; //finished reading
return 1; //successful reading
}
}
reading =(reading+1)%UDP_NUM_BUF; //check next buffer
}while (start!=reading); //stop when all buffers have been checked
isReading=0; //finished reading
return 0; //no incoming datagrams on port
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -