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

📄 tcp.c

📁 ppp拨号程序源代码采用atmel芯片c语言编
💻 C
📖 第 1 页 / 共 4 页
字号:
									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 + -