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

📄 tcp.c

📁 opentcp_mcf5282原代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************************
File:			tcp.c

Date:			10.7.2002

Version:		0.1

Author:			Jari Lahti (jari@violasystems.com)

Description:	This file contains TCP processing functionality

Version Info:	10.7.2002 - First version (JaL)
***************************************************************************************/

#include "opentcp.h"


struct TCPFrame ReceivedTCPPacket;
struct tcb TCPSocket[NO_OF_TCPSOCKETS + 1];

UINT8 tcp_tempbuf[MIN_TCP_HLEN + 1];


/*******************************************************************************/
/*******	TCP API functions											********/
/*******************************************************************************/


/********************************************************************************
Function:		tcp_getsocket

Parameters:		UINT8 soctype - type of socket wanted (client, server or clientserver)
				UINT8 tos	- type of service for socket
				UINT16 tout - timeout of socket in seconds
				INT32 (*listener)(INT8, UINT8, UINT32, UINT32) - listening function

Return val:		INT8 - (-1) = Error
					 - >0 = handle to reserved socket

Date:			21.7.2002

Desc:			Try to get free socket from socket pool and return handle to it
*********************************************************************************/

INT8 tcp_getsocket (UINT8 soctype, UINT8 tos, UINT16 tout, INT32 (*listener)(INT8, UINT8, UINT32, UINT32) )
{
	INT8 i;
	struct tcb* soc;

	if( NO_OF_TCPSOCKETS < 0 )
		return(-1);

	if( NO_OF_TCPSOCKETS == 0 )
		return(-1);

	if( (soctype != TCP_TYPE_SERVER) &&
		(soctype != TCP_TYPE_CLIENT) &&
		(soctype != TCP_TYPE_CLIENT_SERVER) &&
		(soctype != TCP_TYPE_NONE)				)
	{
		DEBUGOUT("Invalid socket type requested\r\n");
		return(-1);
	}

	if(listener == 0)
	{
		DEBUGOUT("ERROR:Event listener function not specified\r\n");
		return(-1);
	}

	DEBUGOUT("Searching for free TCP socket...\r\n");

	for(i=0; i < NO_OF_TCPSOCKETS; i++)
	{
		soc = &TCPSocket[i];			/* Get Socket	*/

		if(soc->state == TCP_STATE_FREE)
		{
			/* We found it	*/

			DEBUGOUT("Free socket found\r\n");

			soc->state = TCP_STATE_RESERVED;
			soc->type = soctype;
			soc->tos = tos;
			soc->event_listener = listener;
			soc->rem_ip = 0;
			soc->remport = 0;
			soc->locport = 0;
			soc->flags = 0;
			soc->tout = (UINT32)tout * TIMERTIC;

			return(i);
		}

	}

	/* We are there so no socket found	*/

	DEBUGOUT("No socket found\r\n");
	return(-1);

}


/********************************************************************************
Function:		tcp_releasesocket

Parameters:		INT8 sochandle - handle to socket to be released

Return val:		INT8 - (-1) = Error
					 - >0 = handle to released socket

Date:			21.7.2002

Desc:			Try to release given socket
*********************************************************************************/

INT8 tcp_releasesocket (INT8 sochandle)
{
	struct tcb* soc;

	if( NO_OF_TCPSOCKETS < 0 )
		return(-1);

	if( NO_OF_TCPSOCKETS == 0 )
		return(-1);

	if( sochandle > NO_OF_TCPSOCKETS )
	{
		DEBUGOUT("Socket handle non-valid\r\n");
		return(-1);
	}

	if( sochandle < 0 )
	{
		DEBUGOUT("Socket handle non-valid\r\n");
		return(-1);
	}

	soc = &TCPSocket[sochandle];		/* Get referense	*/

	if( (soc->state != TCP_STATE_FREE) &&
		(soc->state != TCP_STATE_RESERVED) &&
		(soc->state != TCP_STATE_CLOSED)		)
	{
		DEBUGOUT("Socket is not on valid state to be released\r\n");
		return(-1);
	}

	/* We are there so all OK	*/

	soc->state = TCP_STATE_FREE;
	soc->type = TCP_TYPE_NONE;
	soc->tos = 0;
	soc->event_listener = 0;
	soc->rem_ip = 0;
	soc->remport = 0;
	soc->locport = 0;
	soc->flags = 0;

	return(sochandle);

}

/********************************************************************************
Function:		tcp_listen

Parameters:		INT8 sochandle - handle to socket to be placed on listen
				UINT16 port - port to listen for

Return val:		INT8 - (-1) = Error
					 -  >0 = Handle to listening socket (OK)

Date:			12.7.2002

Desc:			Try to set TCP socket to listen on given port
*********************************************************************************/

INT8 tcp_listen (INT8 sochandle, UINT16 port)
{
	struct tcb* soc;

	if( NO_OF_TCPSOCKETS < 0 )
		return(-1);

	if( NO_OF_TCPSOCKETS == 0 )
		return(-1);

	if( sochandle > NO_OF_TCPSOCKETS )
	{
		DEBUGOUT("Socket handle non-valid\r\n");
		return(-1);
	}

	if( sochandle < 0 )
	{
		DEBUGOUT("Socket handle non-valid\r\n");
		return(-1);
	}

	soc = &TCPSocket[sochandle];		/* Get referense	*/

	if( (soc->type & TCP_TYPE_SERVER) == 0 )
	{
		DEBUGOUT("Socket has no server properties\r\n");
		return(-1);
	}

	if( soc->event_listener == 0)
	{
		DEBUGOUT("ERROR:No event listener function specified\r\n");
		return(-1);
	}


	if( (soc->state != TCP_STATE_RESERVED) &&
		(soc->state != TCP_STATE_LISTENING)	&&
		(soc->state != TCP_STATE_CLOSED) &&
		(soc->state != TCP_STATE_TIMED_WAIT)		)
	{
		DEBUGOUT("Not possible to listen, socket on connected state\r\n");
		return(-1);

	}


	/* Init socket		*/

	soc->state = TCP_STATE_LISTENING;
	//soc->type = TCP_TYPE_SERVER;
	soc->flags = 0;
	soc->rem_ip = 0;
	soc->remport = 0;
	soc->locport = port;
	soc->send_unacked = 0;
	soc->myflags = 0;
	soc->send_next = 0xFFFFFFFF;
	soc->send_mtu = TCP_DEF_MTU;
	//soc->rtt = 0;
	soc->receive_next = 0;
	soc->retries_left = 0;

	DEBUGOUT("TCP listening socket created\r\n");

	return(sochandle);

}

/********************************************************************************
Function:		tcp_connect

Parameters:		UINT8 sochandle - handle to socket to be used
				UINT32 ip - ip address to connect to
				UINT16 rport - port to connect to
				UINT16 myport - local port

Return val:		INT8 - (-1) = Error
					 -  >0 = Connection procedure started (OK)

Date:			21.7.2002

Desc:			Try to connect to remote IP & port
*********************************************************************************/

INT8 tcp_connect (INT8 sochandle, UINT32 ip, UINT16 rport, UINT16 myport )
{
	struct tcb* soc;

	DEBUGOUT("FUNCTION: tcp_connect\r\n");

	if( NO_OF_TCPSOCKETS < 0 )
		return(-1);

	if( NO_OF_TCPSOCKETS == 0 )
		return(-1);

	if( sochandle > NO_OF_TCPSOCKETS )
	{
		DEBUGOUT("Socket handle non-valid\r\n");
		return(-1);
	}

	if( sochandle < 0 )
	{
		DEBUGOUT("Socket handle non-valid\r\n");
		return(-1);
	}

	/* Is the local port defined	*/

	if( myport == 0 )
		myport = tcp_getfreeport();

	if( myport == 0 )
		return(-1);

	soc = &TCPSocket[sochandle];		/* Get referense	*/

	/* Do we have client properties?	*/

	if( (soc->type & TCP_TYPE_CLIENT) == 0 )
	{
		DEBUGOUT("Socket has no client properties\r\n");
		return(-1);
	}

	if( soc->event_listener == 0)
	{
		DEBUGOUT("ERROR:No event listener function specified\r\n");
		return(-1);
	}

	/* Are we on LISTENING, RESERVED or CLOSED state	*/

	if( (soc->state != TCP_STATE_RESERVED) &&
		(soc->state != TCP_STATE_LISTENING) &&
		(soc->state != TCP_STATE_CLOSED)		)
	{
		DEBUGOUT("Socket on unvalid state to initialize CONNECT\r\n");
		return(-1);
	}

	/* Then just set parameters and send SYN	*/

	soc->rem_ip = ip;
	soc->remport = rport;
	soc->locport = myport;
	soc->flags = 0;
	soc->send_mtu = TCP_DEF_MTU;

	/* get initial sequence number	*/

	soc->send_unacked = tcp_initseq();
	soc->send_next = soc->send_unacked + 1;
	soc->myflags = TCP_FLAG_SYN;
	tcp_sendcontrol(sochandle);
	tcp_newstate(soc, TCP_STATE_SYN_SENT);

	return(sochandle);
}


/********************************************************************************
Function:		tcp_send

Parameters:		INT8 sockethandle - handle to processed socket
				UINT8* buf - data buffer (start of user data)
				UINT16 blen - buffer length in bytes (user space)
				UINT16 dlen - legth of data in bytes (user data)

Return val:		INT16 - (-1) Not OK
						>0 Number of bytes sent


Date:			25.7.2002

Desc:			Send user data by using TCP
*********************************************************************************/

INT16 tcp_send (INT8 sockethandle, UINT8* buf, UINT16 blen, UINT16 dlen)
{
	struct tcb* soc;


	DEBUGOUT("Entering to send TCP data packet\r\n");


	if( sockethandle < 0 )
	{
		DEBUGOUT("ERROR:Socket Handle not valid (<0)\r\n");
		return(-1);
	}

	if( sockethandle > NO_OF_TCPSOCKETS )
	{
		DEBUGOUT("ERROR:Socket Handle not valid (>NO_OF_TCPSOCKETS)\r\n");
		return(-1);
	}

	soc = &TCPSocket[sockethandle];				/* Get socket	*/

	if(soc->state != TCP_STATE_CONNECTED)
	{
		DEBUGOUT("TCP is not connected!!\r\n");
		return(-1);
	}

	if(soc->send_unacked != soc->send_next)
	{
		DEBUGOUT("TCP contains unacked data, cannot send more\r\n");
		return(-1);
	}

	if( dlen > blen )
		dlen = blen;

	if(dlen + MIN_TCP_HLEN > soc->send_mtu)
	{
		if(soc->send_mtu > MIN_TCP_HLEN)
			dlen = soc->send_mtu - MIN_TCP_HLEN;
		else
			return(-1);
	}

	soc->send_next += dlen;

	soc->myflags = TCP_FLAG_ACK | TCP_FLAG_PUSH;
	ProcessTCPOut(sockethandle, buf - MIN_TCP_HLEN, blen + MIN_TCP_HLEN + 1, dlen);

	return(dlen);



}

/********************************************************************************
Function:		tcp_close

Parameters:		INT8 sochandle - handle to socket to be closed

Return val:		INT8 - (-2) = Unacked data, try again
					 - (-1) = Error (General)
					 -  >0 = Handle to closed socket (OK)

Date:			21.7.2002

Desc:			Try to close socket to closed state
*********************************************************************************/

INT8 tcp_close (INT8 sochandle)
{
	struct tcb* soc;

	DEBUGOUT("FUNCTION: tcp_close\r\n");

	if( NO_OF_TCPSOCKETS < 0 )
		return(-1);

	if( NO_OF_TCPSOCKETS == 0 )
		return(-1);

	if( sochandle > NO_OF_TCPSOCKETS )
	{
		DEBUGOUT("Socket handle non-valid\r\n");
		return(-1);
	}

	if( sochandle < 0 )
	{
		DEBUGOUT("Socket handle non-valid\r\n");
		return(-1);
	}

	soc = &TCPSocket[sochandle];		/* Get referense	*/

	switch(soc->state)
	{
		case TCP_STATE_LISTENING:
			tcp_newstate(soc, TCP_STATE_CLOSED);
			break;

		case TCP_STATE_SYN_RECEIVED:
			soc->myflags = TCP_FLAG_ACK | TCP_FLAG_FIN;
			soc->send_unacked++;
			soc->send_next++;
			tcp_sendcontrol(sochandle);
			tcp_newstate(soc, TCP_STATE_FINW1);
			break;

		case TCP_STATE_SYN_SENT:

			tcp_newstate(soc, TCP_STATE_CLOSED);

			break;

		case TCP_STATE_FINW1:
		case TCP_STATE_FINW2:
		case TCP_STATE_CLOSING:
		case TCP_STATE_TIMED_WAIT:
		case TCP_STATE_LAST_ACK:

			/* We are closing already	*/

			break;

		case TCP_STATE_CONNECTED:

			/* Is there unacked data?	*/

			if(soc->send_unacked == soc->send_next )
			{
				/* There is no unacked data	*/

				soc->myflags = TCP_FLAG_ACK | TCP_FLAG_FIN;
				soc->send_next++;
				tcp_sendcontrol(sochandle);
				tcp_newstate(soc, TCP_STATE_FINW1);
			}
			else
			{
				/* Can't do much but raise pollable flag to soc->flags		*/
				/* and process it on tcp_poll								*/

				soc->flags |= TCP_INTFLAGS_CLOSEPENDING;


				return(sochandle);
			}

			break;

		default:
			return(-1);
	}

	return(sochandle);

}


/********************************************************************************
Function:		tcp_getstate

Parameters:		INT8 sochandle - handle to socket to be queried

Return val:		INT8 - (-1) = Error
					 -  >0 = State of socket

Date:			21.7.2002

Desc:			Return the state of wanted socket
*********************************************************************************/

INT8 tcp_getstate (INT8 sochandle)
{
	struct tcb* soc;

	if( NO_OF_TCPSOCKETS < 0 )
		return(-1);

	if( NO_OF_TCPSOCKETS == 0 )
		return(-1);

	if( sochandle > NO_OF_TCPSOCKETS )
	{
		DEBUGOUT("Socket handle non-valid\r\n");
		return(-1);
	}

	if( sochandle < 0 )
	{
		DEBUGOUT("Socket handle non-valid\r\n");
		return(-1);
	}

	soc = &TCPSocket[sochandle];		/* Get referense	*/

	return(soc->state);

}

/********************************************************************************
Function:		tcp_checksend

Parameters:		UINT8 sochandle - handle to socket to be inspected

Return val:		INT16 - (-1) = Not possible to send
					 -  >0 = Free buffer space

Date:			23.7.2002

Desc:			Check is it possible to send data by using given socket
*********************************************************************************/

INT16 tcp_checksend (UINT8 sochandle)
{
	struct tcb* soc;

	if( NO_OF_TCPSOCKETS < 0 )
		return(-1);

	if( NO_OF_TCPSOCKETS == 0 )
		return(-1);

	if( sochandle > NO_OF_TCPSOCKETS )
	{
		DEBUGOUT("Socket handle non-valid\r\n");
		return(-1);
	}

	soc = &TCPSocket[sochandle];		/* Get referense	*/

	if(soc->state != TCP_STATE_CONNECTED)
		return(-1);

	if(soc->send_unacked == soc->send_next)
		return(soc->send_mtu);

	return(-1);


}


/********************************************************************************
Function:		tcp_abort

Parameters:		INT8 sochandle - handle to socket to be aborted

Return val:		INT8 - (-1) = Error
					 -  >0 = Handle to aborted socket

Date:			21.7.2002

Desc:			Reset connection and place socket to closed state
*********************************************************************************/

INT8 tcp_abort (INT8 sochandle)
{
	struct tcb* soc;

	DEBUGOUT("FUNCTION: tcp_abort\r\n");

	if( NO_OF_TCPSOCKETS < 0 )
		return(-1);

	if( NO_OF_TCPSOCKETS == 0 )
		return(-1);

	if( sochandle > NO_OF_TCPSOCKETS )
	{
		DEBUGOUT("Socket handle non-valid\r\n");
		return(-1);
	}

	if( sochandle < 0 )
	{
		DEBUGOUT("Socket handle non-valid\r\n");
		return(-1);
	}

	soc = &TCPSocket[sochandle];		/* Get referense	*/

	switch (soc->state)
	{
		case TCP_STATE_FREE:
			return(-1);

		case TCP_STATE_RESERVED:
		case TCP_STATE_CLOSED:
			return(sochandle);

		case TCP_STATE_TIMED_WAIT:
		case TCP_STATE_LISTENING:
			tcp_newstate(soc, TCP_STATE_CLOSED);
			return(sochandle);

		case TCP_STATE_SYN_SENT:
		case TCP_STATE_SYN_RECEIVED:
		case TCP_STATE_CONNECTED:
		case TCP_STATE_FINW1:
		case TCP_STATE_FINW2:
		case TCP_STATE_CLOSING:
		case TCP_STATE_LAST_ACK:

			soc->myflags = TCP_FLAG_RESET;
			tcp_sendcontrol(sochandle);
			tcp_newstate(soc, TCP_STATE_CLOSED);
			return(sochandle);

		default:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -