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

📄 udp.c

📁 ATmega103、ATmega128做的开发板web server源码
💻 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 + -