📄 tcp2.c
字号:
CloseSocket(ps);
else
flags = ACK;
break;
}
if ( flags > 0x00 )
{
if ( flags != ACK )
seq = ps->SND_SEQ++;
else
seq = ps->SND_SEQ;
SendTCP(&ps->remote,
ps->localPort,
ps->remotePort,
seq,
ps->SND_ACK,
flags);
}
}
#else
return;
#endif
}*/
void TCPtickout(void)
{
TCP_SOCKET s;
SOCKET_INFO* ps;
DWORD seq;
BYTE flags;
emInt8 id;
flags = 0x00;
for(s=0;s < MAX_SOCKETS; s++)
{
ps = &TCB[s];
if ( ps->Flags.bIsGetReady || ps->Flags.bIsTxInProgress )
continue;
if ( (ps->smState == TCP_CLOSED) ||
(ps->smState == TCP_LISTEN &&
ps->Flags.bServer == TRUE) )
continue;
id=(s+1);
if((id!=1)&&(id!=2))
continue;
if(emCheckHardTimer(id))
{
ps->RetryCount++;
switch(ps->smState)
{
case TCP_SYN_SENT:
if ( ps->RetryCount < MAX_RETRY_COUNTS )
{
flags = SYN ;
}
else
CloseSocket(ps);
break;
case TCP_SYN_RCVD:
if ( ps->RetryCount < MAX_RETRY_COUNTS )
{
flags = SYN | ACK;
}
else
CloseSocket(ps);
break;
/* case TCP_EST:
if ( ps->RetryCount <= MAX_RETRY_COUNTS )
{
if ( ps->TxBuffer != INVALID_BUFFER )
{
MACSetTxBuffer(ps->TxBuffer, 0);
MACFlush();
}
/*else if(ps->RxCount == 0)
{
flags = 0x00;
ps->RetryCount=0;//有疑问???
}*/
/* else
flags = ACK;
}
else
{
if ( ps->TxBuffer != INVALID_BUFFER )
MACDiscardTx(ps->TxBuffer);
ps->TxBuffer = INVALID_BUFFER;
flags = FIN | ACK;
ps->smState = TCP_FIN_WAIT_1;
}
break; */
case TCP_FIN_WAIT_1:
case TCP_LAST_ACK:
if ( ps->RetryCount > MAX_RETRY_COUNTS )
CloseSocket(ps);
else
flags = FIN;
break;
case TCP_CLOSING:
case TCP_TIMED_WAIT:
if ( ps->RetryCount > MAX_RETRY_COUNTS )
CloseSocket(ps);
else
flags = ACK;
break;
}
if ( flags > 0x00 )
{
if ( flags != ACK )
seq = ps->SND_SEQ++;
else
seq = ps->SND_SEQ;
SendTCP(&ps->remote,
ps->localPort,
ps->remotePort,
seq,
ps->SND_ACK,
flags);
}
}
}
}
/*********************************************************************
* Function: BOOL TCPProcess(NODE_INFO* remote,
* WORD len)
*
* PreCondition: TCPInit() is already called AND
* TCP segment is ready in MAC buffer
*
* Input: remote - Remote node info
* len - Total length of TCP semgent.
*
* Output: TRUE if this function has completed its task
* FALSE otherwise
*
* Side Effects: None
*
* Overview: None
*
* Note: None
********************************************************************/
BOOL TCPProcess(NODE_INFO *remote, WORD len)
{
TCP_HEADER TCPHeader;
PSEUDO_HEADER pseudoHeader;
TCP_SOCKET socket;
WORD_VAL checksum;
BYTE optionsSize;
char i;
BYTE *c;
// Retrieve TCP header.
MACGetArray((BYTE*)&TCPHeader, sizeof(TCPHeader));
c=(BYTE*)&TCPHeader;
for(i=0;i<20;i++)
{
while(!TXSTAbits.TRMT);
putcUSART(*(c++));
}
SwapTCPHeader(&TCPHeader);
// Calculate IP pseudoheader checksum.
pseudoHeader.SourceAddress = remote->IPAddr;
pseudoHeader.DestAddress.v[0] = MY_IP_BYTE1;
pseudoHeader.DestAddress.v[1] = MY_IP_BYTE2;
pseudoHeader.DestAddress.v[2] = MY_IP_BYTE3;
pseudoHeader.DestAddress.v[3] = MY_IP_BYTE4;
pseudoHeader.Zero = 0x0;
pseudoHeader.Protocol = IP_PROT_TCP;
pseudoHeader.TCPLength = len;
SwapPseudoTCPHeader(pseudoHeader);
checksum.Val = ~CalcIPChecksum((BYTE*)&pseudoHeader,
sizeof(pseudoHeader));
// Set TCP packet checksum = pseudo header checksum in MAC RAM.
IPSetRxBuffer(16);
MACPut(checksum.v[0]);
MACPut(checksum.v[1]);
IPSetRxBuffer(0);
// Now calculate TCP packet checksum in NIC RAM - including
// pesudo header.
checksum.Val = CalcTCPChecksum(len);
if ( checksum.Val != TCPHeader.Checksum )
{
MACDiscardRx();
return FALSE;
}
// Skip over options and retrieve all data bytes.
optionsSize = (BYTE)((TCPHeader.DataOffset.Val << 2)-
sizeof(TCPHeader));
len = len - optionsSize - sizeof(TCPHeader);
// Position packet read pointer to start of data area.
IPSetRxBuffer((TCPHeader.DataOffset.Val << 2));
// Find matching socket.
socket = FindMatchingSocket(&TCPHeader, remote);
if ( socket < INVALID_SOCKET )
{
HandleTCPSeg(socket, remote, &TCPHeader, len);
return TRUE;
}
else
{
/*
* If this is an unknown socket, discard it and
* send RESET to remote node.
*/
MACDiscardRx();
//putrsUSART("NO FIND\n");
if ( socket == UNKNOWN_SOCKET )
{
TCPHeader.AckNumber += len;
if ( TCPHeader.Flags.bits.flagSYN ||
TCPHeader.Flags.bits.flagFIN )
TCPHeader.AckNumber++;
SendTCP(remote,
TCPHeader.DestPort,
TCPHeader.SourcePort,
TCPHeader.AckNumber,
TCPHeader.SeqNumber,
RST);
//putrsUSART("SENTRST\n");
}
return FALSE;
}
}
/*********************************************************************
* Function: static void TransmitTCP(NODE_INFO* remote
* TCP_PORT localPort,
* TCP_PORT remotePort,
* DWORD seq,
* DWORD ack,
* BYTE flags,
* BUFFER buffer,
* WORD len)
*
* PreCondition: TCPInit() is already called AND
* TCPIsPutReady() == TRUE
*
* Input: remote - Remote node info
* localPort - Source port number
* remotePort - Destination port number
* seq - Segment sequence number
* ack - Segment acknowledge number
* flags - Segment flags
* buffer - Buffer to which this segment
* is to be transmitted
* len - Total data length for this segment.
*
* Output: A TCP segment is assembled and put to transmit.
*
* Side Effects: None
*
* Overview: None
*
* Note: None
********************************************************************/
static void TransmitTCP(NODE_INFO *remote,
TCP_PORT localPort,
TCP_PORT remotePort,
DWORD tseq,
DWORD tack,
BYTE flags,
BUFFER buffer,
WORD len)
{
WORD_VAL checkSum;
TCP_HEADER header;
TCP_OPTIONS options;
PSEUDO_HEADER pseudoHeader;
/*
* When using SLIP (USART), packet transmission takes some time
* and hence before sending another packet, we must make sure
* that, last packet is transmitted.
* When using ethernet controller, transmission occurs very fast
* and by the time next packet is transmitted, previous is
* transmitted and we do not need to check for last packet.
*/
while( !IPIsTxReady() );
header.SourcePort = localPort;
header.DestPort = remotePort;
header.SeqNumber = tseq;
header.AckNumber = tack;
header.Flags.bits.Reserved2 = 0;
header.DataOffset.Reserved3 = 0;
header.Flags.byte = flags;
// Receive window = MAC Free buffer size - TCP header (20) - IP header (20)
// - ETHERNET header (14 if using NIC) .
header.Window = MACGetFreeRxSize();
#if !defined(STACK_USE_SLIP)
/*
* Limit one segment at a time from remote host.
* This limit increases overall throughput as remote host does not
* flood us with packets and later retry with significant delay.
*/
if ( header.Window >= MAC_RX_BUFFER_SIZE )
header.Window = MAC_RX_BUFFER_SIZE;
else if ( header.Window > 54 )
{
header.Window -= 54;
}
else
header.Window = 0;
#else
if ( header.Window > 40 )
{
header.Window -= 40;
}
else
header.Window = 0;
#endif
header.Checksum = 0;
header.UrgentPointer = 0;
SwapTCPHeader(&header);
len += sizeof(header);
if ( flags & SYN )
{
len += sizeof(options);
options.Kind = TCP_OPTIONS_MAX_SEG_SIZE;
options.Length = 0x04;
// Load MSS in already swapped order.
options.MaxSegSize.v[0] = (MAC_RX_BUFFER_SIZE >> 8); // 0x05;
options.MaxSegSize.v[1] = (MAC_RX_BUFFER_SIZE & 0xff); // 0xb4;
header.DataOffset.Val = (sizeof(header) + sizeof(options)) >> 2;
}
else
header.DataOffset.Val = sizeof(header) >> 2;
// Calculate IP pseudoheader checksum.
pseudoHeader.SourceAddress.v[0] = MY_IP_BYTE1;
pseudoHeader.SourceAddress.v[1] = MY_IP_BYTE2;
pseudoHeader.SourceAddress.v[2] = MY_IP_BYTE3;
pseudoHeader.SourceAddress.v[3] = MY_IP_BYTE4;
pseudoHeader.DestAddress = remote->IPAddr;
pseudoHeader.Zero = 0x0;
pseudoHeader.Protocol = IP_PROT_TCP;
pseudoHeader.TCPLength = len;
SwapPseudoTCPHeader(pseudoHeader);
header.Checksum = ~CalcIPChecksum((BYTE*)&pseudoHeader,
sizeof(pseudoHeader));
checkSum.Val = header.Checksum;
if ( buffer == INVALID_BUFFER )
buffer = MACGetTxBuffer();
IPSetTxBuffer(buffer, 0);
// Write IP header.
IPPutHeader(remote, IP_PROT_TCP, len);
IPPutArray((BYTE*)&header, sizeof(header));
if ( flags & SYN )
IPPutArray((BYTE*)&options, sizeof(options));
IPSetTxBuffer(buffer, 0);
checkSum.Val = CalcTCPChecksum(len);
// Update the checksum.
IPSetTxBuffer(buffer, 16);
MACPut(checkSum.v[1]);
MACPut(checkSum.v[0]);
MACSetTxBuffer(buffer, 0);
MACFlush();
}
/*********************************************************************
* Function: static WORD CalcTCPChecksum(WORD len)
*
* PreCondition: TCPInit() is already called AND
* MAC buffer pointer set to starting of buffer
*
* Input: len - Total number of bytes to calculate
* checksum for.
*
* Output: 16-bit checksum as defined by rfc 793.
*
* Side Effects: None
*
* Overview: This function performs checksum calculation in
* MAC buffer itself.
*
* Note: None
********************************************************************/
static WORD CalcTCPChecksum(WORD len)
{
BOOL lbMSB;
WORD_VAL checkSum;
BYTE Checkbyte;
lbMSB = TRUE;
checkSum.Val = 0;
while( len-- )
{
Checkbyte = MACGet();
if ( !lbMSB )
{
if ( (checkSum.v[0] = Checkbyte+checkSum.v[0]) < Checkbyte)
{
if ( ++checkSum.v[1] == 0 )
checkSum.v[0]++;
}
}
else
{
if ( (checkSum.v[1] = Checkbyte+checkSum.v[1]) < Checkbyte)
{
if ( ++checkSum.v[0] == 0 )
checkSum.v[1]++;
}
}
lbMSB = !lbMSB;
}
checkSum.v[1] = ~checkSum.v[1];
checkSum.v[0] = ~checkSum.v[0];
return checkSum.Val;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -