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

📄 udp.c

📁 嵌入式tcp-ip协议栈 。。。。。。阿萨德
💻 C
字号:
/*
+FHDR------------------------------------------------------------------
Copyright (c),
Tony Yang –51,AVR,ARM firmware developer  
Contact:qq 292942278  e-mail:tony_yang123@sina.com.cn

Abstract:
$Id: udp.c,v 1.3 2006/12/31 16:09:13 tony Exp $
-FHDR-------------------------------------------------------------------
*/ 

#include "config.h"
#include "tcp_ip_cfg.h"
#include "hardware.h"
#include "ethernet.h"
#include "uart0\uart0.h"
#include "icmp.h"
#include "arp.h"
#include "ip.h"



struct UDP_Header * UDp_Header; 

SOCKET UDP_Socket[MAX_UDP_LINKS];
/*本地UDP监听端口表*/
u16 UDP_PORT_Listening[MAX_UDP_Listening_Ports];
/****************************************************************************
* 名称:Queue_PUT
* 功能:查询队列QUEUE有效数据字节数
* 入口:无
* 出口: 队列有效数据字节数
****************************************************************************/
u16 Query_Queue_data_available(SOCKET *QUEUE)
{
    if(QUEUE->Queue_Front == QUEUE->Queue_Rear)
       {
            if(QUEUE->Queue_Full)
              return(MAX_TCP_UDP_DATA_link_buf_len);
            else
              return(0);
       }
    else if(QUEUE->Queue_Rear > QUEUE->Queue_Front)
          {
              return(QUEUE->Queue_Rear - QUEUE->Queue_Front);
          }
         else
          {
              return(MAX_TCP_UDP_DATA_link_buf_len + QUEUE->Queue_Rear - QUEUE->Queue_Front);
          
          }
    return(SUCC);

}

/****************************************************************************
* 名称:Queue_PUT
* 功能:查询队列QUEUE空闲空间
* 入口:无
* 出口: 队列空闲字节数
****************************************************************************/
u16 Query_Queue_freespace(SOCKET *QUEUE)
{
   return(MAX_TCP_UDP_DATA_link_buf_len - Query_Queue_data_available(QUEUE));   

}
/****************************************************************************
* 名称:Queue_PUT
* 功能:QUEUE的队列读取数据
* 入口:buf-数据缓冲区首地址
*       len-数据缓存冲区的长度
* 出口: SUCC FAIL
****************************************************************************/
u8 Queue_GET(SOCKET *QUEUE,u8 * buf,u16 len)
{ 
    u16 data_available,i;

    data_available = Query_Queue_data_available(QUEUE);
    if(len > data_available)
    { 
       len = data_available;
       //return(FAIL);
    }
    if(len >= 1)
      QUEUE->Queue_Full = 0;
    for(i = 0;i < len;i++)
     {
       buf[i] =  QUEUE->UDP_Buff_Queue[(QUEUE->Queue_Front)++];
       if(QUEUE->Queue_Front >= MAX_TCP_UDP_DATA_link_buf_len)
         QUEUE->Queue_Front = 0;  
     }
     
         
    return(SUCC);
}
/****************************************************************************
* 名称:Queue_PUT
* 功能:向QUEUE的队列写入数据
* 入口:buf-数据缓冲区首地址
*       len-数据缓存冲区的长度
* 出口: SUCC FAIL
****************************************************************************/
u8 Queue_PUT(SOCKET *QUEUE,u8 * buf,u16 len)
{
    u16 RreeSpace,i;
    RreeSpace = Query_Queue_freespace(QUEUE);
    if(len > RreeSpace)
    { 
       len = RreeSpace;
       //return(FAIL);
    }
    for(i = 0;i < len;i++)
     {
       QUEUE->UDP_Buff_Queue[(QUEUE->Queue_Rear)++] = buf[i];
       if(QUEUE->Queue_Rear >= MAX_TCP_UDP_DATA_link_buf_len)
         QUEUE->Queue_Rear = 0;  
     }
    if(QUEUE->Queue_Rear == QUEUE->Queue_Front)
       QUEUE->Queue_Full = 1;
    return(SUCC);

}
/****************************************************************************
* 名称:enable_a_port_listen
* 功能:触发一个端口工作为监听状态?
* 入口:PortNUM-端口号
* 出口: SUCC FAIL
****************************************************************************/
u8 enable_a_port_listen(u16 PortNUM)
{
  u16 i;
  for(i = 0 ;i < MAX_UDP_Listening_Ports ;i++)
    if(UDP_PORT_Listening[i] == 0)
    { 
      UDP_PORT_Listening[i] = PortNUM;
      return(SUCC);
    }
  return(FAIL);

}
/****************************************************************************
* 名称:UDP_initial
* 功能:检查端口是否工作为监听状态?
* 入口:PortNUM-端口号
* 出口: SUCC FAIL
****************************************************************************/
u8 check_port_listening(u16 PortNUM)
{
   u16 i;
  for(i = 0 ;i < MAX_UDP_Listening_Ports ;i++)
    if(UDP_PORT_Listening[i] == PortNUM)
    { 
      return(SUCC);
    }
  return(FAIL); 
}
/****************************************************************************
* 名称:UDP_initial
* 功能:UDP模块初始化
* 入口:无
* 出口: 无
****************************************************************************/
void UDP_initial(void)
{
  u16 i;
  u8 j;
  for(i = 0;i < MAX_UDP_LINKS;i++)
  {
    UDP_Socket[i].DEST_Port[0] = 0;
    UDP_Socket[i].DEST_Port[1] = 0;
    UDP_Socket[i].SRC_Port[0] = 0;
    UDP_Socket[i].SRC_Port[1] = 0;
    for(j = 0;j < 4;j++)
    {
      UDP_Socket[i].DEST_IP_Address[j] =0x0;
      UDP_Socket[i].SRC_IP_Address[j] = 0x0;
    }
    UDP_Socket[i].Queue_Rear = 0;
    UDP_Socket[i].Queue_Front = 0;
    UDP_Socket[i].Queue_Full = 0;
    UDP_Socket[i].EN = 0;
  }
  for(i = 0 ;i < MAX_UDP_Listening_Ports ;i++)
    UDP_PORT_Listening[i] = 0;

}


 
/****************************************************************************
* 名称:Rcv_UDP_PKT
* 功能:查找四元组,一个四无组表示一个服务器与客户器连接
* 入口:pkt-UDP数据报的首地址,
*       index-UDP_Socket的索引
*       IP-源/目的首地址
* 出口: 无
****************************************************************************/
u8 Seek_4_elements(u8 * pkt,u16 * index,u8 *IP)
{
   u16 i,j,flag;
  
  for(i = 0 ;i < MAX_UDP_Listening_Ports ;i++)
  {
    if(!UDP_Socket[i].EN)
       continue;
    /*检查PKT的源端口*/
    if(pkt[0] != UDP_Socket[i].DEST_Port[1] || pkt[1] != UDP_Socket[i].DEST_Port[0])
        continue;
    if(pkt[2] != UDP_Socket[i].SRC_Port[1] || pkt[3] != UDP_Socket[i].SRC_Port[0])
        continue;
    /*检查PKT的目的地址*/
    SendByte(0x55);SendByte(0x55);SendByte(0x55);SendByte(0x55);
    flag = SUCC;
    for(j = 0;j < 4;j++)
    {
      if(IP[j] != UDP_Socket[i].DEST_IP_Address[j] )
         {
            flag = FAIL;
            break; 
         }
    }
   if(flag == SUCC)
     {
       *index = i; 
       return(SUCC);
     }
  }
  return(FAIL);
}
/****************************************************************************
* 名称:Rcv_UDP_PKT
* 功能:写一个四元组,表示一个服务器与客户器连接
* 入口:pkt-UDP数据报的首地址,
        index-UDP_Socket的索引
        IP-源/目的首地址
* 出口: 无
****************************************************************************/
void Write_4_element(u8 * pkt,u16 index,u8 *IP)
{
  u16 i;
    UDP_Socket[index].EN = 1;
  for(i = 0;i<4;i++)
  {
   UDP_Socket[index].DEST_IP_Address[i] = IP[i];
   UDP_Socket[index].SRC_IP_Address[i] = IP[4+i];
  }
  
     UDP_Socket[index].DEST_Port[0] = pkt[1];
     UDP_Socket[index].DEST_Port[1] = pkt[0];
     
     
     UDP_Socket[index].SRC_Port [0] = pkt[3];
     UDP_Socket[index].SRC_Port [1] = pkt[2];


  
}
/****************************************************************************
* 名称:Send_UDP_PKT
* 功能:数据报发送
* 入口:无
* 出口: 无
****************************************************************************/
void Send_UDP_PKT(struct _pkst *TxdData,SOCKET *Sock)
{
  u8 buf[1516];
  u16 len,i,checksum;
  struct _pkst Txddata;
  len = 8 + TxdData->length;
  for(i = 0;i < 4;i++)
  {
    buf[i] = Sock->SRC_IP_Address[i];
    buf[4 + i] = Sock->DEST_IP_Address[i]; 
  }
  buf[8] = 0;
  buf[9] = UDP;
  buf[10] = len>>8;
  buf[11] = len & 0xff;
  /*填写UDP首部*/
  buf[12] = Sock->SRC_Port[1];
  buf[13] = Sock->SRC_Port[0];
  buf[14] = Sock->DEST_Port[1];
  buf[15] = Sock->DEST_Port[0];
  buf[16] = len >> 8;
  buf[17] = len & 0xff;
  buf[18] = 0;
  buf[19] = 0;
  for(i = 0;i < TxdData->length;i++)
     buf[i + 20] = TxdData->DAPTR[i];
  checksum = CheckSumUdp(buf,len + 12 );
  buf[18] = checksum >> 8;
  buf[19] = checksum & 0xff;
  checksum = CheckSumUdp(buf,len + 12 );
  SendByte(checksum >> 8); SendByte(checksum & 0xff);
  Txddata.DAPTR = buf+12;  
  Txddata.length = 8;  
  Txddata.STPTR = TxdData;				
  Send_IP_PKT(&Txddata,Sock->DEST_IP_Address,UDP);
}
/****************************************************************************
* 名称:Rcv_UDP_PKT
* 功能:数据报接收
* 入口:pkt-UDP数据报的首地址,
        lenght-数据报的长度
        IP-源/目的首地址
* 出口: 无
****************************************************************************/
void Rcv_UDP_PKT(u8 *pkt,u16 length,u8 * IP)
{
  struct _pkst TxdData1;
  u16 index;
  u16 freespace,i,checksum;
  
  SendByte('y');SendByte('y');
  SendByte('y');SendByte('y');
  /*计算UDP首部校验和*/
  pkt = pkt - 12;/*填充UDP伪首部*/
  pkt[0] = 0;
  //pkt[1] = UDP;
  pkt[2] = pkt[16];
  pkt[3] = pkt[17];
  pkt = pkt + 12;
  checksum = CheckSumUdp(pkt - 12,length + 12);
  if(checksum != 0)
    return;
  //SendByte(checksum >> 8);SendByte(checksum & 0xff);
  SendByte('y');SendByte('y');
  SendByte('y');SendByte('y');
  
  UDp_Header = (struct UDP_Header *) pkt;
  /*检查目的端口是否在监听当中*/
  if(check_port_listening(swap_int16(UDp_Header->DEST_Port)) == FAIL)
  {
  
    return;
    
  }
  SendByte('y');SendByte('y');
  SendByte('y');SendByte('y');

  
  /*查找一个四元组*/
  if(Seek_4_elements(pkt,&index,IP) == FAIL)
  {
    SendByte('a');SendByte('a');
    SendByte('a');SendByte('a');
   /*分配一个UDP_Socket,写入四元组*/
   for(i = 0;i < MAX_UDP_LINKS;i++)
    {
      if(!UDP_Socket[i].EN)
            break;
      
    }
   if(i >= MAX_UDP_LINKS)
       return; 
   Write_4_element(pkt,i,IP);
   index = i; 
  }
  

  SendByte('z');SendByte('z');
  SendByte('z');SendByte('z');

  for(i = 0;i<length - 8;i++)
  {
    SendByte(*(pkt + 8 +i));
  }
  /*将数据写入UDP_Socket*/
  freespace =  Query_Queue_freespace(&UDP_Socket[index]);
  if((length - 8) > freespace)
      return; //溢出
   else
   {
     Queue_PUT(&UDP_Socket[index],pkt + 8,length - 8);
        
   }
  
  freespace =  Query_Queue_freespace(&UDP_Socket[index]); 
  SendByte(freespace & 0xff);SendByte(freespace >> 8);
  
  TxdData1.STPTR = NULL;
  TxdData1.length = length - 8;
  TxdData1.DAPTR = pkt + 8;
 // Send_UDP_PKT(&TxdData1,&UDP_Socket[index]);


  return; 

   
}
/*
+FFTR--------------------------------------------------------------------
$Log: udp.c,v $
Revision 1.3  2006/12/31 16:09:13  tony
由于write_file慢(1KB/S)导致FTP服务器put file失序,不写file时序正常

Revision 1.2  2006/12/31 16:04:37  tony
增加FTP代码,SOCKET_status字段


-FFTR--------------------------------------------------------------------
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -