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

📄 tcp.c

📁 udp,tcp/ip在智能家居芯片上的代码实现.包括芯片NE64的网络驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
					
					if(soc->type & TCP_TYPE_SERVER )
						tcp_newstate(soc, TCP_STATE_LISTENING);
					else
						tcp_newstate(soc, TCP_STATE_CLOSED);
					
					soc->myflags = TCP_FLAG_RESET;
					tcp_sendcontrol(handle);
					
					/* Inform application	*/

					soc->event_listener(handle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);
				
					handle++;
		
					return;
				}	
				
				break;
			
			default:
				break;	
			
		}
		
		/* Go to next socket if there was no event	*/
		
		handle++;
		
	}
	
}



/** \brief Initialize TCP module
 *	\ingroup core_initializer
 * 	\author 
 *		\li Jari Lahti (jari.lahti@violasystems.com)
 *	\date 21.07.2002
 *	\return
 *		\li -1 - error
 *		\li >0 - number of sockets initialized
 *	\warning 
 *		\li This function <b>must</b> be invoked at startup before any
 *		other TCP functions are invoked.
 *
 *	This function initializes all sockets and corresponding tcbs to known
 *	state. Timers are also allocated for each socket and everything is
 *	brought to a predefined state.
 *
 */
INT8 tcp_init (void)
{
	UINT16 i;
	INT16 h;
	struct tcb* soc;
	
	if( NO_OF_TCPSOCKETS < 0 )
		return(-1);
	
	if( NO_OF_TCPSOCKETS == 0 )
		return(0);
	
	TCP_DEBUGOUT("Initializing TCP");
	
	for(i=0; i < NO_OF_TCPSOCKETS; i++) {
		soc = &tcp_socket[i];			/* Get Socket	*/
		h = -1;
		
		soc->state = TCP_STATE_FREE;
		soc->type = TCP_TYPE_NONE;
		soc->flags = 0;
		soc->rem_ip = 0;
		soc->remport = 0;
		soc->locport = 0;
		soc->myflags = 0;
		soc->send_mtu = TCP_DEF_MTU;
		soc->tos = 0;
		soc->tout = 0;
		soc->event_listener = 0;
		
		/* Reserve Timers	*/
		
		h = get_timer();
		
		/*
		if( h < 0 ) {
			TCP_DEBUGOUT("\n\rERROR:Error getting timer for TCP Socket!\n\r");
			return(-1);
		}
		*/
		
		init_timer(h,0);					/* No timeout	*/
		
		soc->persist_timerh = h;
		
		h = get_timer();
		
		/*
		if( h < 0 ) {
			TCP_DEBUGOUT("\n\rERROR:Error getting timer for TCP Socket!\n\r");
			return(-1);
		}
		*/
		
		init_timer(h,0);					/* No timeout	*/
		
		soc->retransmit_timerh = h;
		
		soc->retries_left = 0;		 
		
		TCP_DEBUGOUT(".");
		
	
	}
	
	TCP_DEBUGOUT("\n\rTCP Initialized\n\r");
	
	/* Return number of sockets initialized	*/
	
	return(i+1);
	

}




/*******************************************************************************/
/*******	TCP Internal functions										********/
/*******************************************************************************/


/** \brief Check and process the received TCP frame
 *	\ingroup periodic_functions
 * 	\author 
 *		\li Jari Lahti (jari.lahti@violasystems.com)
 *	\date 12.07.2002
 *	\param frame pointer to received ip_frame structure
 *	\param len length of data contained in IP datagram (in bytes)
 *	\return 
 *		\li -1 - Error (packet not OK, or not TCP,or something else)
 *		\li >0 - Packet OK
 *
 *	Invoke this function to process received TCP frames. See main_demo.c for
 *	an example on how to accomplish this.
 */
INT16 process_tcp_in (struct ip_frame* frame, UINT16 len)
{
	struct tcb* soc;
	UINT16 hlen;
	UINT8 olen;
	UINT16 dlen;
	UINT16 i;
	INT8 sochandle;	
	INT16 temp;
	
	/* Is this TCP?	*/
	
	TCP_DEBUGOUT("Processing TCP...\n\r");
	
	if( frame->protocol != IP_TCP ) {
		TCP_DEBUGOUT("ERROR: The protocol is not TCP\n\r");
		return(-1);
	}
	
	/* Calculate checksum for received packet	*/

	
	NETWORK_RECEIVE_INITIALIZE(frame->buf_index);
	
	if( tcp_check_cs (frame, len) == 1) {
		TCP_DEBUGOUT("TCP Checksum OK\n\r");
	} else {
		TCP_DEBUGOUT("ERROR:TCP Checksum failed\r\n");
		return(-1);
	} 

	/* Get the header	*/
	
	/* Get the header	*/
	
	NETWORK_RECEIVE_INITIALIZE(frame->buf_index);
	

	received_tcp_packet.sport = RECEIVE_NETWORK_W();

	
	received_tcp_packet.dport = RECEIVE_NETWORK_W();
	
	received_tcp_packet.seqno = (((UINT32)RECEIVE_NETWORK_B()) << 24);
	received_tcp_packet.seqno |= (((UINT32)RECEIVE_NETWORK_B()) << 16);
	received_tcp_packet.seqno |= (((UINT32)RECEIVE_NETWORK_B()) << 8);
	received_tcp_packet.seqno |= RECEIVE_NETWORK_B();
	
	received_tcp_packet.ackno = (((UINT32)RECEIVE_NETWORK_B()) << 24);
	received_tcp_packet.ackno |= (((UINT32)RECEIVE_NETWORK_B()) << 16);
	received_tcp_packet.ackno |= (((UINT32)RECEIVE_NETWORK_B()) << 8);
	received_tcp_packet.ackno |= RECEIVE_NETWORK_B();

	received_tcp_packet.hlen_flags = RECEIVE_NETWORK_W();
	received_tcp_packet.window = RECEIVE_NETWORK_W();
	
	received_tcp_packet.checksum = RECEIVE_NETWORK_W();
	
	received_tcp_packet.urgent = RECEIVE_NETWORK_W();
	
	/* Little check for options	*/
	
	hlen = received_tcp_packet.hlen_flags & 0xF000;
	hlen >>= 10;
	
	if( hlen < MIN_TCP_HLEN ) {
		TCP_DEBUGOUT("ERROR: Received TCP Header too short\r\n");
		return(-1);
	}
	
	if(hlen == MIN_TCP_HLEN)
		TCP_DEBUGOUT("TCP does not contain options\r\n");
	
	olen = hlen - MIN_TCP_HLEN;
	
	if( olen > MAX_TCP_OPTLEN ) {
		TCP_DEBUGOUT("ERROR: Received TCP header contains too long option field\r\n");
		return(-1);
	}
	
	/* Calculate data length	*/
	
	if( hlen > len ) {
		TCP_DEBUGOUT("ERROR: TCP header longer than packet\r\n");
		return(-1);
	}
	
	dlen = len - hlen - olen;
	
	/* Get options (if any)	*/
	
	for(i=0; i<olen;i++)
		received_tcp_packet.opt[i] = RECEIVE_NETWORK_B();
		
	/* Try to find rigth socket to process with		*/
	
	sochandle = tcp_mapsocket(frame, &received_tcp_packet);
	
	if(sochandle < 0) {
		TCP_DEBUGOUT("ERROR: Processing TCP packet failed\r\n");
		tcp_sendreset(&received_tcp_packet, frame->sip);
		return(-1);
	}
	
	received_tcp_packet.buf_index = frame->buf_index + hlen;
	NETWORK_RECEIVE_INITIALIZE(received_tcp_packet.buf_index);
	
	
	
	/* Get socket reference	*/
	
	soc = &tcp_socket[sochandle];
	
	/* Process the packet on TCP State Machine		*/
	
	switch(soc->state) {
		case TCP_STATE_CONNECTED:
		
			TCP_DEBUGOUT("CONNECTED State\r\n");
			
			/* Check for RESET	*/
			
			if(received_tcp_packet.hlen_flags & TCP_FLAG_RESET)	{
				TCP_DEBUGOUT("ERROR:Reset received\r\n");

				/* Inform application	*/

				soc->event_listener(sochandle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);				
				
				if(soc->type & TCP_TYPE_SERVER)
					tcp_newstate(soc, TCP_STATE_LISTENING);
				else
					tcp_newstate(soc, TCP_STATE_CLOSED);
					
				return(-1);
			}
			
			/* Check for SYN (If the peer didn't get our SYN+ACK or ACK)	*/
			
			if( received_tcp_packet.hlen_flags & TCP_FLAG_SYN )	{
				/* Is it the SYN+ACK we have already ACKed but maybe ACK lost?	*/
				
				if( received_tcp_packet.hlen_flags & TCP_FLAG_ACK )	{
					/* It's SYN+ACK but how about sequence	*/
					
					if( (received_tcp_packet.seqno + 1) == soc->receive_next ) {
					
						if( received_tcp_packet.ackno == soc->send_next ) {
						
							TCP_DEBUGOUT("Received SYN+ACK again\r\n");
							
							/* ACK the SYN	*/
							soc->myflags = TCP_FLAG_ACK;
							tcp_sendcontrol(sochandle);
							return(0);
						}
						
					}
				
				 /* It is maybe SYN again so it haven't get our SYN + ACK	*/
				 /* Let our retransmission handle it						*/
				 
				 return(0);
				
				
				}
			
			}
			
			/* Do we have unacked data?		*/
			
			if( soc->send_unacked != soc->send_next ) {
			
				/* Yep, is the ACK valid?	*/
				
				if( (received_tcp_packet.hlen_flags & TCP_FLAG_ACK) == 0) {
				
					TCP_DEBUGOUT("Packet without ACK and unacked data. Packet not processed\r\n");
					return(0);
				}
				
				if( received_tcp_packet.ackno == soc->send_next ) {
				
					/* We don't have unacked data now	*/
				
					soc->send_unacked = soc->send_next;
				
					/* Inform application	*/
				
					soc->event_listener(sochandle, TCP_EVENT_ACK, soc->rem_ip, soc->remport);
				
				}

			
			}
			
			/* Is the sequence OK	*/
			
			if(soc->receive_next != received_tcp_packet.seqno)
			{
				/* Out of range, inform what we except	*/
			
				DEBUGOUT("Too big sequence number received\r\n");
				
				soc->myflags = TCP_FLAG_ACK;
				tcp_sendcontrol(sochandle);
				return(0);
			}
			
			/* Generate data event to application	*/
				
#ifdef IPv6
			soc->event_listener(sochandle, TCP_EVENT_DATA, (IPv6Addr *)&dlen, 0);
#else
			soc->event_listener(sochandle, TCP_EVENT_DATA, dlen, 0);
#endif
			soc->receive_next += dlen;			
					
			/* Is the FIN flag set?	*/
			
			if( received_tcp_packet.hlen_flags & TCP_FLAG_FIN )	{
				TCP_DEBUGOUT("Other end want's to close\r\n");
				
				/* Inform application if we don't have unacked data	*/
				
				if( soc->send_unacked == soc->send_next) {
				
					soc->event_listener(sochandle, TCP_EVENT_CLOSE, soc->rem_ip, soc->remport);
				
					/* ACK FIN and set our own FIN	*/
				
					soc->receive_next++;
					soc->send_next++;
					soc->myflags = TCP_FLAG_ACK | TCP_FLAG_FIN;
				
					tcp_newstate(soc, TCP_STATE_LAST_ACK);
					tcp_sendcontrol(sochandle);
				
					return(0);
				}
			}
			
			/* ACK the data if there was it	*/
			
			if(dlen) {
				soc->myflags = TCP_FLAG_ACK;
				tcp_sendcontrol(sochandle);
			}
			
			tcp_newstate(soc, TCP_STATE_CONNECTED);			
			

			return(0);
			
		
			break;
	
		case TCP_STATE_FREE:
			
			/* Reset connection	*/
			tcp_sendreset(&received_tcp_packet, frame->sip);
			return(-1);
		
			break;
		
		case TCP_STATE_CLOSED:
			
			/* Reset connection	*/
			tcp_sendreset(&received_tcp_packet, frame->sip);
			return(-1);		
		
			break;
		
		case TCP_STATE_LISTENING:
		
			TCP_DEBUGOUT("LISTENING State...\r\n");
		
			/* Check Flags	*/
			
			if(received_tcp_packet.hlen_flags & TCP_FLAG_RESET) {
				TCP_DEBUGOUT("ERROR:Reset received\r\n");
				tcp_newstate(soc, TCP_STATE_LISTENING);
				return(-1);
			}
			
			if(received_tcp_packet.hlen_flags & TCP_FLAG_ACK) {
				TCP_DEBUGOUT("ERROR:Ack received\r\n");
				tcp_newstate(soc, TCP_STATE_LISTENING);
				/* Reset connection	*/
				tcp_sendreset(&received_tcp_packet, frame->sip);
				return(-1);	
			}
			
			if((received_tcp_packet.hlen_flags & TCP_FLAG_SYN) == 0) {
				TCP_DEBUGOUT("ERROR:No SYN set on packet\r\n");
				tcp_newstate(soc, TCP_STATE_LISTENING);
				/* Reset connection	*/
				tcp_sendreset(&received_tcp_packet, frame->sip);
				return(-1);
			}
			
			/* OK, SYN received	*/
			
			/* Inform application and see if accepted	*/
			
			temp = (INT16)soc->event_listener(sochandle, TCP_EVENT_CONREQ, soc->rem_ip, soc->remport);
			
			if( temp == -1)	{
				TCP_DEBUGOUT("Application disregarded connection request\r\n");
				tcp_sendreset(&received_tcp_packet, frame->sip);
				return(-1);
			}
			
			if( temp == -2 ) {
				TCP_DEBUGOUT("Application wants to think about accepting conreq\r\n");
				return(1);
			}
			
			/* The connection request was accepted	*/
			
			TCP_DEBUGOUT("Next state SYN_RECEIVED\r\n");
			if(soc->flags & TCP_INTFLAGS_CLOSEPENDING)
				soc->flags ^= TCP_INTFLAGS_CLOSEPENDING;
			tcp_newstate(soc, TCP_STATE_SYN_RECEIVED);
			soc->receive_next = received_tcp_packet.seqno + 1;	/* Ack SYN		*/
			soc->send_unacked = tcp_initseq();
			
			soc->myflags = TCP_FLAG_SYN | TCP_FLAG_ACK;
			tcp_sendcontrol(sochandle);
			soc->send_next = soc->send_unacked + 1;
			
			return(1);
			
			break;
			
		case TCP_STATE_SYN_RECEIVED:
		
			TCP_DEBUGOUT("SYN_RECEIVED State...\r\n");
			
			/* Check Flags	*/
			
			if(received_tcp_packet.hlen_flags & TCP_FLAG_RESET)	{
				TCP_DEBUGOUT("ERROR:Reset received\r\n");
				
				/* Inform application	*/
				
				soc->event_listener(sochandle, TCP_EVENT_ABORT, soc->rem_ip, soc->remport);
				
				if(soc->type & TCP_TYPE_SERVER)
					tcp_newstate(soc, TCP_STATE_LISTENING);
				else
					tcp_newstate(soc, TCP_STATE_CLOSED);
					
				return(-1);
			}
			
			/* Is it SYN+ACK (if we are the because of simultaneous open)	*/
			
			if( (received_tcp_packet.hlen_flags & TCP_FLAG_SYN) &&
				(received_tcp_packet.hlen_flags & TCP_FLAG_ACK)	) {			
				
				if( received_tcp_packet.ackno != soc->send_next ) {
					TCP_DEBUGOUT("SYN+ACK received but wrong Ack\n\r");
					return(-1);
				}
				
				TCP_DEBUGOUT("SYN+ACK received, this side established\n\r");
				
				/* Get peer's seq number	*/
				
				soc->receive_next =  received_tcp_packet.seqno;
				soc->receive_next++;							/* ACK SYN	*/

⌨️ 快捷键说明

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