?? tcp_ip.c
字號:
*(WORD*)&TCP_TxFrame2[IP_FLAGS_FRAG_OFS] = 0;
*(WORD*)&TCP_TxFrame2[IP_TTL_PROT_OFS] = swap_bytes((DEFAULT_TTL << 8) | PROT_TCP);
*(WORD*)&TCP_TxFrame2[IP_HEAD_CHKSUM_OFS] = 0;
memcpy( &TCP_TxFrame2[IP_SOURCE_OFS], &TCP_Local_IP, 4);
memcpy( &TCP_TxFrame2[IP_DESTINATION_OFS], &TCP_RemoteIP, 4);
*(WORD*)&TCP_TxFrame2[IP_HEAD_CHKSUM_OFS] = TCP_CalcChecksum(&TCP_TxFrame2[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0);
// TCP
*(WORD*)&TCP_TxFrame2[TCP_SRCPORT_OFS] = swap_bytes(TCP_LocalPort);
*(WORD*)&TCP_TxFrame2[TCP_DESTPORT_OFS] = swap_bytes(TCP_RemotePort);
WriteDWBE(&TCP_TxFrame2[TCP_SEQNR_OFS], TCP_Seq_Nr);
WriteDWBE(&TCP_TxFrame2[TCP_ACKNR_OFS], TCP_Ack_Nr);
// data bytes to accept
*(WORD*)&TCP_TxFrame2[TCP_WINDOW_OFS] = swap_bytes(MAX_TCP_RX_SIZE);
// initalize checksum
*(WORD*)&TCP_TxFrame2[TCP_CHKSUM_OFS] = 0;
*(WORD*)&TCP_TxFrame2[TCP_URGENT_OFS] = 0;
// if SYN, we want to use the MSS option
if (TCPCode & TCP_CODE_SYN)
{
// TCP header length = 24
*(WORD*)&TCP_TxFrame2[TCP_DATA_CODE_OFS] = swap_bytes(0x6000 | TCPCode);
// MSS option
*(WORD*)&TCP_TxFrame2[TCP_DATA_OFS] = swap_bytes(TCP_OPT_MSS);
// max. length of TCP-data we accept
*(WORD*)&TCP_TxFrame2[TCP_DATA_OFS + 2] = swap_bytes(MAX_TCP_RX_SIZE);
*(WORD*)&TCP_TxFrame2[TCP_CHKSUM_OFS] = TCP_CalcChecksum(&TCP_TxFrame2[TCP_SRCPORT_OFS], TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE, 1);
TCP_TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE + TCP_OPT_MSS_SIZE;
}
else
{
// TCP header length = 20
*(WORD*)&TCP_TxFrame2[TCP_DATA_CODE_OFS] = swap_bytes(0x5000 | TCPCode);
*(WORD*)&TCP_TxFrame2[TCP_CHKSUM_OFS] = TCP_CalcChecksum(&TCP_TxFrame2[TCP_SRCPORT_OFS], TCP_HEADER_SIZE, 1);
TCP_TxFrame2Size = ETH_HEADER_SIZE + IP_HEADER_SIZE + TCP_HEADER_SIZE;
}
TCP_TransmitControl |= TCP_SEND_FRAME2;
}
/******************************************************************************
* TCP_IP_STACK: TCP_Prep_TCP_DATA_FRAME()
*
* Purpose:
* prepares the TxFrame1-buffer to send a payload-packet
*
* Actions:
*
*****************************************************************************/
MC void TCP_Prep_TCP_DATA_FRAME()
{
// Ethernet
memcpy( &TCP_TxFrame1[ETH_DA_OFS], &TCP_RemoteMAC, 6);
memcpy( &TCP_TxFrame1[ETH_SA_OFS], &TCP_MyMAC, 6);
*(WORD*)&TCP_TxFrame1[ETH_TYPE_OFS] = FRAME_IP;
// IP
*(WORD*)&TCP_TxFrame1[IP_VER_IHL_TOS_OFS] = swap_bytes(IP_VER_IHL | IP_TOS_D);
*(WORD*)&TCP_TxFrame1[IP_TOTAL_LENGTH_OFS] = swap_bytes( IP_HEADER_SIZE + TCP_HEADER_SIZE + TCP_Tx_Data_Count);
*(WORD*)&TCP_TxFrame1[IP_IDENT_OFS] = 0;
*(WORD*)&TCP_TxFrame1[IP_FLAGS_FRAG_OFS] = 0;
*(WORD*)&TCP_TxFrame1[IP_TTL_PROT_OFS] = swap_bytes((DEFAULT_TTL << 8) | PROT_TCP);
*(WORD*)&TCP_TxFrame1[IP_HEAD_CHKSUM_OFS] = 0;
memcpy( &TCP_TxFrame1[IP_SOURCE_OFS], &TCP_Local_IP, 4);
memcpy( &TCP_TxFrame1[IP_DESTINATION_OFS], &TCP_RemoteIP, 4);
*(WORD*)&TCP_TxFrame1[IP_HEAD_CHKSUM_OFS] = TCP_CalcChecksum(&TCP_TxFrame1[IP_VER_IHL_TOS_OFS], IP_HEADER_SIZE, 0);
// TCP
*(WORD*)&TCP_TxFrame1[TCP_SRCPORT_OFS] = swap_bytes(TCP_LocalPort);
*(WORD*)&TCP_TxFrame1[TCP_DESTPORT_OFS] = swap_bytes(TCP_RemotePort);
WriteDWBE(&TCP_TxFrame1[TCP_SEQNR_OFS], TCP_Seq_Nr);
WriteDWBE(&TCP_TxFrame1[TCP_ACKNR_OFS], TCP_Ack_Nr);
// TCP header length = 20
*(WORD*)&TCP_TxFrame1[TCP_DATA_CODE_OFS] = swap_bytes(0x5000 | TCP_CODE_ACK | TCP_CODE_PSH);
// data bytes to accept
*(WORD*)&TCP_TxFrame1[TCP_WINDOW_OFS] = swap_bytes(MAX_TCP_RX_SIZE);
*(WORD*)&TCP_TxFrame1[TCP_CHKSUM_OFS] = 0;
*(WORD*)&TCP_TxFrame1[TCP_URGENT_OFS] = 0;
*(WORD*)&TCP_TxFrame1[TCP_CHKSUM_OFS] = TCP_CalcChecksum(&TCP_TxFrame1[TCP_SRCPORT_OFS], TCP_HEADER_SIZE + TCP_Tx_Data_Count, 1);
}
/******************************************************************************
* TCP_IP_STACK: CalcChecksum()
*
* Purpose:
* calculates the TCP/IP checksum. if 'IsTCP != 0', the TCP pseudo-header
* will be included.
*
* Actions:
*
*****************************************************************************/
MC WORD TCP_CalcChecksum(BYTE *Start, WORD Count, BYTE IsTCP)
{
DWORD Sum = 0;
// if we've a TCP frame...
// ...include TCP pseudo-header
if (IsTCP)
{
Sum += TCP_Local_IP[0];
Sum += TCP_Local_IP[1];
Sum += TCP_RemoteIP[0];
Sum += TCP_RemoteIP[1];
// TCP header length plus data length
Sum += swap_bytes(Count);
Sum += swap_bytes(PROT_TCP);
}
// sum words
while (Count > 1)
{
//access data pointed to as WORD
Sum += *(WORD*)Start;
// increment pointer and decrement count
Start += 2;
Count -= 2;
}
// add left-over byte, if any
if (Count)
Sum += *(BYTE*)Start;
// fold 32-bit sum to 16 bits
while (Sum >> 16)
Sum = (Sum & 0xFFFF) + (Sum >> 16);
return ~Sum;
}
/******************************************************************************
* TCP_IP_STACK: TCP_StartRetryTimer()
*
* Purpose:
* starts the timer as a retry-timer (used for retransmission-timeout)
*
* Actions:
*
*****************************************************************************/
MC void TCP_StartRetryTimer()
{
TCP_Timer = 0;
TCP_RetryCounter = TCP_MAX_RETRIES;
TCP_Flags |= TCP_TIMER_RUNNING;
TCP_Flags |= TCP_TIMER_TYPE_RETRY;
}
/******************************************************************************
* TCP_IP_STACK: TCP_StartTimeWaitTimer()
*
* Purpose:
* starts the timer as a 'TIME_WAIT'-timer (used to finish a TCP-session)
*
* Actions:
*
*****************************************************************************/
MC void TCP_StartTimeWaitTimer()
{
TCP_Timer = 0;
TCP_Flags |= TCP_TIMER_RUNNING;
TCP_Flags &= ~TCP_TIMER_TYPE_RETRY;
}
/******************************************************************************
* TCP_IP_STACK: TCP_RestartTimer()
*
* Purpose:
* restarts the timer
*
* Actions:
*
*****************************************************************************/
MC void TCP_RestartTimer()
{
TCP_Timer = 0;
}
/******************************************************************************
* TCP_IP_STACK: TCP_StopTimer()
*
* Purpose:
* stops the timer
*
* Actions:
*
*****************************************************************************/
MC void TCP_StopTimer()
{
TCP_Flags &= ~TCP_TIMER_RUNNING;
}
/******************************************************************************
* TCP_IP_STACK: TCP_HandleRetransmission()
*
* Purpose:
* if a retransmission-timeout occured, check which packet to resend.
*
* Actions:
*
*****************************************************************************/
MC void TCP_HandleRetransmission()
{
switch (TCP_LastFrameSent)
{
case ARP_REQUEST :
{
TCP_Prep_ARP_REQUEST();
break;
}
case TCP_SYN_FRAME :
{
TCP_Prep_TCP_FRAME(TCP_CODE_SYN);
break;
}
case TCP_SYN_ACK_FRAME :
{
TCP_Prep_TCP_FRAME(TCP_CODE_SYN | TCP_CODE_ACK);
break;
}
case TCP_FIN_FRAME :
{
TCP_Prep_TCP_FRAME(TCP_CODE_FIN | TCP_CODE_ACK);
break;
}
case TCP_DATA_FRAME :
{
TCP_TransmitControl |= TCP_SEND_FRAME1;
break;
}
}
}
/******************************************************************************
* TCP_IP_STACK: TCP_HandleTimeout()
*
* Purpose:
* if all retransmissions failed, close connection and indicate an error
*
* Actions:
*
*****************************************************************************/
MC void TCP_HandleTimeout()
{
TCP_StateMachine = CLOSED;
if ((TCP_Flags & (TCP_ACTIVE_OPEN | TCP_IP_ADDR_RESOLVED)) == TCP_ACTIVE_OPEN)
// indicate an error to user
TCP_SocketStatus = TCP_SOCK_ERR_ARP_TIMEOUT;
else
TCP_SocketStatus = TCP_SOCK_ERR_TCP_TIMEOUT;
// clear all flags
TCP_Flags = 0;
}
/******************************************************************************
* TCP_IP_STACK: TCP_Copy_Frame()
*
* Purpose:
* Copies prepared frame to LAN transmit buffer
*
* Actions:
*
*****************************************************************************/
MC void TCP_Copy_Frame(WORD length, BYTE *Frame)
{
#ifndef USE_16_BITS
DWORD *data_src = (DWORD*) Frame;
DWORD *data_dst = LAN_tx_packet.data;
int i;
LAN_tx_packet.length = length;
LAN_tx_packet.busy = 1;
for (i=0; i<=(length>>2); i++)
*data_dst++ = *data_src++;
return;
#else
WORD *data_src = (WORD*) Frame;
WORD *data_dst = LAN_tx_packet.data;
int i;
LAN_tx_packet.length = length;
LAN_tx_packet.busy = 1;
for (i=0; i<=(length>>1); i++)
*data_dst++ = *data_src++;
return;
#endif
}
/******************************************************************************
* TCP_IP_STACK: swap_bytes()
*
* Purpose:
* swaps lower 8bits with higher 8bits and vice versa
*
* Actions:
*
*****************************************************************************/
inline WORD swap_bytes(DWORD in)
{
return ((in&0xff)<<8) | ((in&0xff00)>>8);
#if 0
WORD rval;
asm("r5 = %1.l (z); %1 >>=8; r5 <<=8; %0 = r5 |%1;"
: "=D" (rval)
: "D" (in)
: "r5");
return rval;
#endif
}
/******************************************************************************
* TCP_IP_STACK: WriteDWBE()
*
* Purpose:
* swaps lower 8bits with higher 8bits and vice versa
*
* Actions:
*
*****************************************************************************/
inline void WriteDWBE(BYTE* Add, DWORD Data)
{
*Add++ = Data >> 24;
*Add++ = Data >> 16;
*Add++ = Data >> 8;
*Add = Data;
}
/******************************************************************************
* TCP_IP_STACK: get_cyles()
*
* Purpose:
* returns --XXXX-- out of CYCLES register for ISN Generation
*
* Actions:
*
*****************************************************************************/
inline WORD get_cycles()
{
WORD rval;
asm("%0 = CYCLES; %0 >>= 9;"
: "=D" (rval)
:
: );
return rval;
}
// end-of-file
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -