?? tcp.c
字號:
#define TCP_GLOBALS
/*#include "config.h"
#include "../include/cfg_net.h" */
#include "..\User\includes.h"
OS_EVENT *AppSemSend[MAX_TCP_LINKS];
OS_EVENT *AppSemCon[MAX_TCP_LINKS];
OS_EVENT *AppSemDisc[MAX_TCP_LINKS];
struct Socket_Type TcpStatus[MAX_TCP_LINKS];
tcp_send Tcp_Packed;
/**********************************************************************
**函數原型: unsigned int CheckSum(unsigned int xdata *check,unsigned int length)
**入口參數:?check : 被校驗數據起始地址
length : 被校驗數據長度,單位字
**出口參數: 無
**返 回 值: ~((sum)&0xffff))
**說 明: 計算校驗和
************************************************************************/
//=================================================================================
uint16 CheckSumTcp1(uint8 num,uint16 length)
{
uint32 sum=0;
uint16 i;
for (i=0;i<6;i++)
{
sum = sum + ((uint32)TcpStatus[num].TcpDHeadUint8[2*i]<<8)+(uint32)TcpStatus[num].TcpDHeadUint8[2*i+1];
}
length=length-12;
i=0;
while(i<(length/2))
{
sum = sum + ((uint32)TcpStatus[num].TcpHeadUint8[2*i]<<8)+(uint32)TcpStatus[num].TcpHeadUint8[2*i+1];
i++;
}
if(length&0x0001)//長度為奇數個時,要進行該操作
{
//sum = sum + (uint32)(TcpStatus[num].TcpHeadUint8[2*i])<<8;
sum = sum + (uint32)(TcpStatus[num].TcpHeadUint8[2*i])*256;
}
sum = (sum&0x0000ffff) + ((sum>>16)&0x0000ffff);//高16位和低16位相加
if(sum & 0xffff0000)
{//表示有進位
sum++;
if(sum & 0xffff0000)
{//表示有進位
sum++;
}
}
return ( (uint16)(~((sum)&0xffff)) );
}
void Tcp_Initial(void)
{
uint8 i;
for(i=0;i<MAX_TCP_LINKS;i++)
{
TcpStatus[i].Dest_Port=0;
TcpStatus[i].My_Port=0;
TcpStatus[i].State=TCP_STATE_CLOSED;
TcpStatus[i].StaSem=0;
TcpStatus[i].Send_Next=0;
TcpStatus[i].ResendTime=0;
TcpStatus[i].ResendState=0;
TcpStatus[i].RecPassSeq=0;
TcpStatus[i].SenPassSeq=0;
TcpStatus[i].SenFutureSeq=0;
TcpStatus[i].RecPassAck=0;
TcpStatus[i].SenPassAck=0;
TcpStatus[i].RecFutureAck=0;
TcpStatus[i].Snd_Window=MAX_TCP_DATA;
TcpStatus[i].TcpDataQWrPtr=0;
TcpStatus[i].TcpDataQRdPtr=0;
AppSemSend[i]= OSSemCreate(0);
AppSemCon[i]= OSSemCreate(0);
AppSemDisc[i]= OSSemCreate(0);
}
Tcp_Packed.TcpDHead.rev=0;
Tcp_Packed.TcpDHead.NextProtocal=6;
}
/**********************************************************************
**函數原型: void Send_Reset()
**入口參數: 無
**出口參數: 無
**返 回 值: 無
**功能說明: 發送TCP_RST數據報文,復位對方連接
******************************************************************/
void Send_Reset(uint8 num)
{
uint16 i;
struct _pkst TxdData;
i=Tcp_Packed.Tcp.SourcePort;
Tcp_Packed.Tcp.SourcePort=Tcp_Packed.Tcp.DestPort;
Tcp_Packed.Tcp.DestPort=i;
Tcp_Packed.Tcp.offset=0x50;
Tcp_Packed.Tcp.window=TcpStatus[num].Snd_Window;
Tcp_Packed.Tcp.urg=0;
Tcp_Packed.Tcp.Crc=0;
/*
Tcp_Packed.Tcp.tcpdata[0]=0X02;
Tcp_Packed.Tcp.tcpdata[1]=0X04;
Tcp_Packed.Tcp.tcpdata[2]=MAX_TCP_DATA/256;
Tcp_Packed.Tcp.tcpdata[3]=MAX_TCP_DATA%256;
Tcp_Packed.Tcp.tcpdata[4]=0X01;
Tcp_Packed.Tcp.tcpdata[5]=0X01;
Tcp_Packed.Tcp.tcpdata[6]=0X01;
Tcp_Packed.Tcp.tcpdata[7]=0X01;*/
//*********添加TCP假頭**********//
Tcp_Packed.TcpDHead.rev=0;
Tcp_Packed.TcpDHead.NextProtocal=6;
Tcp_Packed.TcpDHead.TotalLen=20;
//Tcp_Packed.Tcp.Crc=CheckSumTcp((uint16 EX_RAM *)&Tcp_Packed,Tcp_Packed.TcpDHead.TotalLen+12);
TxdData.STPTR=NULL;
TxdData.length=Tcp_Packed.TcpDHead.TotalLen;
TxdData.DAPTR=(uint8 EX_RAM *)&Tcp_Packed.Tcp;
Send_Ip_Frame
(
&TxdData,
TcpStatus[num].Dest_Ip,
TcpStatus[num].My_Ip,
6
);
//memcpy (&(TcpStatus[num].resend_data),&(Tcp_Packed.Tcp) , Tcp_Packed.TcpDHead.TotalLen);
TcpStatus[num].ResendLength=Tcp_Packed.TcpDHead.TotalLen;
}
/**********************************************************************
**函數原型: void Delete_Socket()
**入口參數: 無
**出口參數: 無
**返 回 值: 無
**功能說明: 撤銷本地連接,并清空重發緩沖區
******************************************************************/
void Delete_Socket(uint8 num)
{
uint16 i;
OS_ENTER_CRITICAL();
if((TcpStatus[num].StaSem&0x80)==0x80)
{
TcpStatus[num].State=TCP_STATE_LISTEN;
TcpStatus[num].StaSem=0x82;
}
else
{
TcpStatus[num].State=TCP_STATE_CLOSED;
TcpStatus[num].StaSem=0;
TcpStatus[num].My_Port=0;
TcpStatus[num].My_Ip[0]=0;
TcpStatus[num].My_Ip[1]=0;
TcpStatus[num].My_Ip[2]=0;
TcpStatus[num].My_Ip[3]=0;
}
do
{
i=OSSemAccept(AppSemCon[num]);
}while(i!=0);
do
{
i=OSSemAccept(AppSemSend[num]);
}while(i!=0);
do
{
i=OSSemAccept(AppSemDisc[num]);
}while(i!=0);
TcpStatus[num].RecPassSeq=0;
TcpStatus[num].RecPassAck=0;
TcpStatus[num].SenPassSeq=0;
TcpStatus[num].SenPassAck=0;
TcpStatus[num].RecFutureAck=0;
TcpStatus[num].SenFutureSeq=0;
TcpStatus[num].ResendState=0;//表示該重發緩沖區沒有數據
TcpStatus[num].ResendTime=0;
TcpStatus[num].Dest_Port=0;
TcpStatus[num].Dest_Ip[0]=0;
TcpStatus[num].Dest_Ip[1]=0;
TcpStatus[num].Dest_Ip[2]=0;
TcpStatus[num].Dest_Ip[3]=0;
TcpStatus[num].TcpDataQWrPtr=0;
TcpStatus[num].TcpDataQRdPtr=0;
OS_EXIT_CRITICAL();
}
void Tcp_Listen(uint8 num)
{
static uint32 initalseq=32451;
struct _pkst TxdData;
if(Tcp_Packed.Tcp.control&TCP_SYN)
{
TcpStatus[num].State=TCP_STATE_SYN_RCVD;//TCP_STATE_SYN_RCVD;//Tcp_SYN_Rec;
//TcpStatus[num].Dest_Ip[0]=Tcp_Packed.TcpDHead.DestId[0];
//TcpStatus[num].Dest_Ip[1]=Tcp_Packed.TcpDHead.DestId[1];
//TcpStatus[num].Dest_Ip[2]=Tcp_Packed.TcpDHead.DestId[2];
//TcpStatus[num].Dest_Ip[3]=Tcp_Packed.TcpDHead.DestId[3];
TcpStatus[num].Dest_Port=Tcp_Packed.Tcp.SourcePort;//對方端口
//TcpStatus[num].My_Port=Tcp_Packed.Tcp.DestPort;
TcpStatus[num].IRS=Tcp_Packed.Tcp.SeqNum;//對方的初始化順序號
TcpStatus[num].RecPassSeq=Tcp_Packed.Tcp.SeqNum;
TcpStatus[num].RecPassAck=0;
TcpStatus[num].SenPassSeq=initalseq;
TcpStatus[num].SenPassAck=TcpStatus[num].RecPassSeq+1;
TcpStatus[num].RecFutureAck=initalseq+1;
TcpStatus[num].SenFutureSeq=initalseq+1;
TcpStatus[num].Rcv_Next=Tcp_Packed.Tcp.SeqNum+1;//對方的順序號,用于確認
TcpStatus[num].ISS=TcpStatus[num].Send_Next;//我的初始化順序號
TcpStatus[num].Sent_UnAck=TcpStatus[num].ISS;//我的未確認得序號
TcpStatus[num].Send_Next=TcpStatus[num].ISS+1;//我的順序號,用于發送
TcpStatus[num].My_Wl1=Tcp_Packed.Tcp.SeqNum;//seq
TcpStatus[num].My_Wl2=TcpStatus[num].Send_Next;
TcpStatus[num].Rcv_Window=Tcp_Packed.Tcp.window;//對方的WINDOW大小
TcpStatus[num].Snd_Window=MAX_TCP_DATA;//通知對方本地最大接收1024字節的包,用于流控
TcpStatus[num].Dest_Max_Seg_Size=MAX_TCP_DATA;//默認為560
if(Tcp_Packed.Tcp.offset>50)
if(Tcp_Packed.Tcp.tcpdata[0]==0x02)
if(Tcp_Packed.Tcp.tcpdata[1]==0x04) //0204為最大segment選項
{
TcpStatus[num].Dest_Max_Seg_Size=Tcp_Packed.Tcp.tcpdata[2]*256+Tcp_Packed.Tcp.tcpdata[3];
}
TcpStatus[num].My_Max_Seg_Size=MAX_TCP_DATA;//本地機可以接受最大的以太網數據包
//********************************************//
TcpStatus[num].TcpHeadUint8[0]=(TcpStatus[num].My_Port&0xff00)>>8;
TcpStatus[num].TcpHeadUint8[1]=TcpStatus[num].My_Port&0x00ff;
Tcp_Packed.Tcp.SourcePort=TcpStatus[num].My_Port;
TcpStatus[num].TcpHeadUint8[2]=(TcpStatus[num].Dest_Port&0xff00)>>8;
TcpStatus[num].TcpHeadUint8[3]=TcpStatus[num].Dest_Port&0x00ff;
Tcp_Packed.Tcp.DestPort=TcpStatus[num].Dest_Port;
TcpStatus[num].TcpHeadUint8[4]=(TcpStatus[num].SenPassSeq&0xff000000)>>24;
TcpStatus[num].TcpHeadUint8[5]=(TcpStatus[num].SenPassSeq&0x00ff0000)>>16;
TcpStatus[num].TcpHeadUint8[6]=(TcpStatus[num].SenPassSeq&0x0000ff00)>>8;
TcpStatus[num].TcpHeadUint8[7]=(TcpStatus[num].SenPassSeq&0x000000ff);
Tcp_Packed.Tcp.SeqNum=TcpStatus[num].ISS;
TcpStatus[num].TcpHeadUint8[8]=(TcpStatus[num].SenPassAck&0xff000000)>>24;
TcpStatus[num].TcpHeadUint8[9]=(TcpStatus[num].SenPassAck&0x00ff0000)>>16;
TcpStatus[num].TcpHeadUint8[10]=(TcpStatus[num].SenPassAck&0x0000ff00)>>8;
TcpStatus[num].TcpHeadUint8[11]=(TcpStatus[num].SenPassAck&0x000000ff);
Tcp_Packed.Tcp.AckNum=TcpStatus[num].Rcv_Next;
TcpStatus[num].TcpHeadUint8[12]=0x70;
Tcp_Packed.Tcp.offset=0x70;
TcpStatus[num].TcpHeadUint8[13]=0x12;
Tcp_Packed.Tcp.control=0x12; //syn+ack
TcpStatus[num].TcpHeadUint8[14]=(TcpStatus[num].Snd_Window&0xff00)>>8;
TcpStatus[num].TcpHeadUint8[15]=TcpStatus[num].Snd_Window&0x00ff;
Tcp_Packed.Tcp.window=TcpStatus[num].Snd_Window;
TcpStatus[num].TcpHeadUint8[16]=0;
TcpStatus[num].TcpHeadUint8[17]=0;
Tcp_Packed.Tcp.Crc=0;
TcpStatus[num].TcpHeadUint8[18]=0;
TcpStatus[num].TcpHeadUint8[19]=0;
Tcp_Packed.Tcp.urg=0;
//******添加TCP頭選項*************//
TcpStatus[num].TcpHeadUint8[20]=0X02;
Tcp_Packed.Tcp.tcpdata[0]=0X02;
TcpStatus[num].TcpHeadUint8[21]=0X04;
Tcp_Packed.Tcp.tcpdata[1]=0X04;
TcpStatus[num].TcpHeadUint8[22]=MAX_TCP_DATA/256;
Tcp_Packed.Tcp.tcpdata[2]=MAX_TCP_DATA/256;
TcpStatus[num].TcpHeadUint8[23]=MAX_TCP_DATA%256;
Tcp_Packed.Tcp.tcpdata[3]=MAX_TCP_DATA%256;
TcpStatus[num].TcpHeadUint8[24]=0X01;
Tcp_Packed.Tcp.tcpdata[4]=0X01;
TcpStatus[num].TcpHeadUint8[25]=0X01;
Tcp_Packed.Tcp.tcpdata[5]=0X01;
TcpStatus[num].TcpHeadUint8[26]=0X01;
Tcp_Packed.Tcp.tcpdata[6]=0X01;
TcpStatus[num].TcpHeadUint8[27]=0X01;
Tcp_Packed.Tcp.tcpdata[7]=0X01;
//*********添加TCP假頭**********//
TcpStatus[num].TcpDHeadUint8[0]=0;
Tcp_Packed.TcpDHead.rev=0;
TcpStatus[num].TcpDHeadUint8[1]=6;
Tcp_Packed.TcpDHead.NextProtocal=6;
TcpStatus[num].TcpDHeadUint8[2]=0;
TcpStatus[num].TcpDHeadUint8[3]=28;
Tcp_Packed.TcpDHead.TotalLen=28;
TcpStatus[num].TcpDHeadUint8[4]=TcpStatus[num].My_Ip[0];
TcpStatus[num].TcpDHeadUint8[5]=TcpStatus[num].My_Ip[1];
TcpStatus[num].TcpDHeadUint8[6]=TcpStatus[num].My_Ip[2];
TcpStatus[num].TcpDHeadUint8[7]=TcpStatus[num].My_Ip[3];
TcpStatus[num].TcpDHeadUint8[8]=TcpStatus[num].Dest_Ip[0];
TcpStatus[num].TcpDHeadUint8[9]=TcpStatus[num].Dest_Ip[1];
TcpStatus[num].TcpDHeadUint8[10]=TcpStatus[num].Dest_Ip[2];
TcpStatus[num].TcpDHeadUint8[11]=TcpStatus[num].Dest_Ip[3];
//Tcp_Packed.Tcp.Crc=CheckSumTcp((uint16 EX_RAM *)&Tcp_Packed,Tcp_Packed.TcpDHead.TotalLen+12);
Tcp_Packed.Tcp.Crc=CheckSumTcp1(num,40);//12+28
TcpStatus[num].TcpHeadUint8[16]=(Tcp_Packed.Tcp.Crc&0xff00)>>8;;
TcpStatus[num].TcpHeadUint8[17]=Tcp_Packed.Tcp.Crc&0x00ff;
//memcpy (&(TcpStatus[num].resend_data),&(Tcp_Packed.Tcp) , Tcp_Packed.TcpDHead.TotalLen);
TcpStatus[num].ResendLength=Tcp_Packed.TcpDHead.TotalLen;
TcpStatus[num].TcpDataQWrPtr=0;
TcpStatus[num].TcpDataQRdPtr=0;
TxdData.STPTR=NULL;
TxdData.length=Tcp_Packed.TcpDHead.TotalLen;
TxdData.DAPTR=TcpStatus[num].TcpHeadUint8;
Send_Ip_Frame
(
&TxdData,
TcpStatus[num].Dest_Ip,
TcpStatus[num].My_Ip,
6
);
}
else if(Tcp_Packed.Tcp.control&TCP_RST)
{;}
/*
else
{
Send_Reset(num);
}*/
}
/**********************************************************************
**函數原型: void Tcp_SYN_Rec( )
**入口參數: 無
**出口參數: 無
**返 回 值:?無
**功能說明: 從tcp_listen接收到syn后,即可進入該狀態
** : 該狀態可接收tcp_syn和tcp_ack或tcp_rst
**************************************************************/
void Tcp_SYN_Rec(uint8 num)
{struct _pkst TxdData;
if(Tcp_Packed.Tcp.control&(TCP_RST))//reset//處理reset,對方不接受請求
{
Delete_Socket(num);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -