📄 tcp.c
字号:
break;
case TCP_LAST_ACK : SendDebugRStr(tcp_str32);
break;
case TCP_TIME_WAIT : SendDebugRStr(tcp_str33);
break;
default : SendDebugRStr(tcp_str34);
break;
}
}
void TCP_DisplaySocketState(T_TCP_Socket *Socket)
{
if (Socket == NULL) return;
TCP_DisplaySocketStage(Socket);
SendDebugStr("\n");
SendDebugRStr(TCP_Str50);
sprintf((char*)ScratchPad, "%lums\n", u32_Get(&Socket->ConnectTime));
SendDebugStr((char*)ScratchPad);
SendDebugRStr(TCP_Str51);
sprintf((char*)ScratchPad, "%lums\n", u32_Get(&Socket->LastRxData));
SendDebugStr((char*)ScratchPad);
SendDebugRStr(TCP_Str52);
sprintf((char*)ScratchPad, "%u\n", Socket->TheirMaxSegSize);
SendDebugStr((char*)ScratchPad);
SendDebugRStr(TCP_Str53);
sprintf((char*)ScratchPad, "%lu\n", Socket->TheirSequenceNum);
SendDebugStr((char*)ScratchPad);
SendDebugRStr(TCP_Str54);
sprintf((char*)ScratchPad, "%lu\n", Socket->OurSequenceNum);
SendDebugStr((char*)ScratchPad);
SendDebugRStr(TCP_Str55);
sprintf((char*)ScratchPad, "%u\n", Socket->TheirWindowSize);
SendDebugStr((char*)ScratchPad);
SendDebugRStr(TCP_Str56);
sprintf((char*)ScratchPad, "%d\n", Socket->OurLastBytesSent);
SendDebugStr((char*)ScratchPad);
SendDebugRStr(TCP_Str57);
IP_Str((char*)ScratchPad, Socket->RemoteIP.ip32);
strcat((char*)ScratchPad, "\n");
SendDebugStr((char*)ScratchPad);
SendDebugRStr(TCP_Str58);
sprintf((char*)ScratchPad, "%u\n", Socket->RemotePort);
SendDebugStr((char*)ScratchPad);
SendDebugRStr(TCP_Str59);
sprintf((char*)ScratchPad, "%u\n", Socket->LocalPort);
SendDebugStr((char*)ScratchPad);
SendDebugRStr(TCP_Str60);
sprintf((char*)ScratchPad, "%ums\n", Socket->RoundTripTime);
SendDebugStr((char*)ScratchPad);
SendDebugRStr(TCP_Str61);
sprintf((char*)ScratchPad, "%u\n", Socket->Retries);
SendDebugStr((char*)ScratchPad);
SendDebugRStr(TCP_Str62);
sprintf((char*)ScratchPad, "%ums\n", u16_Get(&Socket->Retry_Timer));
SendDebugStr((char*)ScratchPad);
SendDebugRStr(TCP_Str63);
sprintf((char*)ScratchPad, "%d\n", Socket->TxBufferRd);
SendDebugStr((char*)ScratchPad);
SendDebugRStr(TCP_Str64);
sprintf((char*)ScratchPad, "%d\n", Socket->TxBufferWr);
SendDebugStr((char*)ScratchPad);
SendDebugRStr(TCP_Str65);
sprintf((char*)ScratchPad, "%d\n", Socket->RxBufferRd);
SendDebugStr((char*)ScratchPad);
SendDebugRStr(TCP_Str66);
sprintf((char*)ScratchPad, "%d\n", Socket->RxBufferWr);
SendDebugStr((char*)ScratchPad);
}
#endif
// ******************************************************************************************
// set the socket stage
void TCP_SocketStage(T_TCP_Socket *Socket, T_TCP_Stage Stage)
{
if (Socket == NULL) return; //
//
Socket->Stage = Stage; // set the socket stage
Socket->Retries = 0; //
u16_Put(&Socket->Retry_Timer, Socket->RoundTripTime * TCP_Retry_Time); // send next packet asap
#ifdef Debug
TCP_DisplaySocketStage(Socket);
#endif
}
// ******************************************************************************************
void TCP_UpdateRoundTripTime(T_TCP_Socket *Socket, u16 Time)
{
// update our record of roughtly how long it takes for the total round trip time for tcp data.
// we the value to work out how long we should wait for tx retries
if (Socket == NULL) return; //
//
if (Socket->RoundTripTime < Time) //
Socket->RoundTripTime = Time; // bump straight up
else //
{ //
Socket->RoundTripTime += Time; // average round trip time
Socket->RoundTripTime >>= 1; // "
} //
//
if (Socket->RoundTripTime < 100) Socket->RoundTripTime = 100; // no lower than 100ms
else //
if (Socket->RoundTripTime > 6000) Socket->RoundTripTime = 6000; // no higher than 6000ms
}
// ******************************************************************************************
bool TCP_CloseSocket(T_TCP_Socket *Socket)
{ // close the tcp socket
if (Socket == NULL) return true; // socket is closed
switch (Socket->Stage)
{
case TCP_CLOSED :
case TCP_LISTEN : break; // close the socket
case TCP_SYN_SENT : TCP_SocketStage(Socket, TCP_CLOSED);
TCP_SendPacket(Socket, TCP_RST);
return false;
case TCP_SYN_RECEIVED :
case TCP_ESTABLISHED : TCP_SocketStage(Socket, TCP_FIN_WAIT_1);
TCP_SendPacket(Socket, TCP_FIN | TCP_ACK);
default : return false;
}
TCP_SocketStage(Socket, TCP_CLOSED); //
//
return true; // socket is closed
}
T_TCP_Socket *TCP_SocketListen(u16 Port)
{ // create a new tcp socket and set it to listen mode
T_TCP_Socket *Socket; //
//
#ifdef StaticTCPSocket
Socket = TCP_Socket; // static socket
#else
Socket = malloc(sizeof(T_TCP_Socket)); // allocate memory for a tcp socket
if (Socket == NULL) //
{ //
#ifdef Debug
SendDebugRStr(tcp_Str35); //
#endif
return NULL; // failed to get a socket
} //
#endif
//
memset(Socket, 0, sizeof(T_TCP_Socket)); //
Socket->LocalPort = Port; // select the port we are gona listen on
Socket->OurSequenceNum = Random32; // our sequence number
Socket->RoundTripTime = TCP_RoundTripTime; // default average round trip time - ms
Socket->TheirMaxSegSize = TCP_Default_MSS; //
Socket->OutGoing = false; //
Socket->AckDelay = 65000; //
//
TCP_SocketStage(Socket, TCP_LISTEN); // open a tcp listening socket
//
return Socket; // success
}
T_TCP_Socket *TCP_OpenSocket(u32 IP, u16 Port)
{ // create a tcp socket and initiate an out going connection
T_TCP_Socket *Socket; //
//
if ((!IP) || (!Port)) return NULL; //
//
#ifdef StaticTCPSocket
Socket = TCP_Socket; // static socket
#else
Socket = malloc(sizeof(T_TCP_Socket)); // allocate memory for a tcp socket
if (Socket == NULL) //
{ //
#ifdef Debug
SendDebugRStr(tcp_Str35); //
#endif
return NULL; // failed to get a socket
} //
#endif
//
memset(Socket, 0, sizeof(T_TCP_Socket)); //
//
if (TCP_TmpPort < TCP_OutGoingPortLow) TCP_TmpPort = TCP_OutGoingPortLow; //
else //
if (TCP_TmpPort >= TCP_OutGoingPortHigh) TCP_TmpPort = TCP_OutGoingPortHigh;//
//
Socket->LocalPort = TCP_TmpPort++; // select the port we are gona listen on
Socket->RemotePort = Port; // select the port we are gona listen on
Socket->RemoteIP.ip32 = IP; // select the port we are gona listen on
Socket->OurSequenceNum = Random32; // our sequence number
Socket->TheirMaxSegSize = TCP_Default_MSS; //
Socket->RoundTripTime = TCP_RoundTripTime; // default average round trip time - ms
Socket->OutGoing = true; //
Socket->AckDelay = 65000; //
//
TCP_SocketStage(Socket, TCP_SYN_SENT); // start a an outgoing connection
u16_Put(&Socket->Retry_Timer, Socket->RoundTripTime * TCP_Retry_Time); // next packet asap
//
return Socket; // success
}
// ******************************************************************************************
int TCP_RxSaveData(T_TCP_Socket *Socket, u8 *Src, int len)
{ // save the received tcp data into the sockets rx ring buffer - the executive reads the dat back from this buffer
int i;
if ((Socket == NULL) || (!Src) || (len <= 0)) return 0; //
//
i = RingBufBytesFree(sizeof(Socket->RxBuffer), Socket->RxBufferRd, Socket->RxBufferWr); // number of bytes free in our buffer
if (len > i) len = i; //
//
i = CopyToRingBuffer(Socket->RxBuffer, Src, Socket->RxBufferWr, sizeof(Socket->RxBuffer), len); //
Socket->RxBufferWr += i; //
while (Socket->RxBufferWr >= sizeof(Socket->RxBuffer)) Socket->RxBufferWr -= sizeof(Socket->RxBuffer); //
//
u32_Put(&Socket->LastRxData, 0); // reset timer
Socket->TheirSequenceNum += (u32)i; // the next sequence number we will be expecting
Socket->AckDelay = 0; // delayed ack send back
// Socket->Flags |= TCP_ACK; // we need to ACK the data they sent us
//
#ifdef Debug
sprintf((char*)ScratchPad, "RxBufferRd:%d RxBufferWr:%d\n", Socket->RxBufferRd, Socket->RxBufferWr);
SendDebugStr((char*)ScratchPad);
#endif
//
return i; //
}
int TCP_RxBytes(T_TCP_Socket *Socket)
{ // return how many tcp Rx bytes are in the sockets rx ring buffer
if (Socket == NULL) return 0; //
return RingBufBytes(sizeof(Socket->RxBuffer), Socket->RxBufferRd, Socket->RxBufferWr); // number of bytes in our buffer
}
int TCP_RxData(T_TCP_Socket *Socket, u8 *Dest, int len)
{ // get a number of bytes from the tcp rx ring buffer - this is called from the executive
int i;
if ((Socket == NULL) || (!Dest) || (len <= 0)) return 0; //
//
i = TCP_RxBytes(Socket); // number of bytes waiting for them to collect
if (i <= 0) return 0; // none
if (len > i) len = i; // limit number of bytes their gona get
//
i = CopyFromRingBuffer(Dest, Socket->RxBuffer, Socket->RxBufferRd, sizeof(Socket->RxBuffer), len); //
Socket->RxBufferRd += i; //
while (Socket->RxBufferRd >= sizeof(Socket->RxBuffer)) Socket->RxBufferRd -= sizeof(Socket->RxBuffer); //
//
return i; //
}
int TCP_TxFree(T_TCP_Socket *Socket)
{ // return how much space we have in the sockets tx ring buffer
if (Socket == NULL) return 0;
return RingBufBytesFree(sizeof(Socket->TxBuffer), Socket->TxBufferRd, Socket->TxBufferWr);
}
int TCP_TxData(T_TCP_Socket *Socket, u8 *Src, int len)
{ // save data into the sockets tx ring buffer - this will get sent down the tcp link
int i;
if ((Socket == NULL) || (!Src) || (len <= 0) || (Socket->Stage != TCP_ESTABLISHED)) return 0; //
//
i = TCP_TxFree(Socket); // number of bytes free in our buffer
if (len > i) len = i; // limit number of bytes we will send
if (len > Socket->TheirMaxSegSize) len = Socket->TheirMaxSegSize; // they can only acept a certain amount
i = CopyToRingBuffer(Socket->TxBuffer, Src, Socket->TxBufferWr, sizeof(Socket->TxBuffer), len); // copy the bytes into the tcp tx buffer
Socket->TxBufferWr += i; //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -