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

📄 tcp.c

📁 ENC system full - ENC28J60
💻 C
📖 第 1 页 / 共 2 页
字号:
							tcp_sockets[socketnum].seq = nic_buffer_to_seq(&buffer[TCP_POS_ACK]);							tcp_send_packet(buffer, socketnum, (TCP_FIN_FLAG), 0);							#if TCP_DEBUG							softuart_puts_progmem("LAST_ACK");							#endif							break;						///LAST_ACK						case(TCP_STATE_LAST_ACK):							//socket is closed							tcp_close_socket(socketnum);							#if TCP_DEBUG							softuart_puts_progmem("LAST_ACK->CLOSED");							#endif							break;						///FIN WAIT 1						case(TCP_STATE_FIN_WAIT1):							//if we receive FIN							tcp_sockets[socketnum].ack = nic_buffer_to_seq(&buffer[TCP_POS_SEQ])+1;														#if TCP_DEBUG							softuart_puts_progmem("FIN_WAIT1->");							#endif							if (tcp_header_flags == TCP_FIN_FLAG){								//goto CLOSING & send an ack:								tcp_sockets[socketnum].state = TCP_STATE_CLOSING;								tcp_send_packet(buffer, socketnum, (TCP_ACK_FLAG), 0);								#if TCP_DEBUG								softuart_puts_progmem("CLOSING");								#endif							}else if(tcp_header_flags == (TCP_FIN_FLAG | TCP_ACK_FLAG)){								//FIN&ACK -> send ACK & close !								if (nic_buffer_to_seq(&buffer[TCP_POS_ACK]) == tcp_sockets[socketnum].seq){									//close socket!									tcp_close_socket(socketnum);									#if TCP_DEBUG									softuart_puts_progmem("CLOSED !");									#endif								}else{									//both have sent the connection close request, we must wait for an last ack									tcp_sockets[socketnum].state = TCP_STATE_LAST_ACK;									#if TCP_DEBUG									softuart_puts_progmem("LAST ACK !");									#endif								}								tcp_send_packet(buffer, socketnum, (TCP_ACK_FLAG), 0);							}else{								//ACK -> goto FIN WAIT2								tcp_sockets[socketnum].state = TCP_STATE_FIN_WAIT2;								#if TCP_DEBUG								softuart_puts_progmem("FIN_WAIT2");								#endif							}							break;												///FIN WAIT 2						case(TCP_STATE_FIN_WAIT2):							//if we receive FIN							tcp_sockets[socketnum].ack = nic_buffer_to_seq(&buffer[TCP_POS_SEQ])+1;							//tcp_sockets[socketnum].seq = nic_buffer_to_seq(&buffer[TCP_POS_ACK]);							if (tcp_header_flags & TCP_FIN_FLAG){								//FIN -> goto TIMED WAIT								tcp_sockets[socketnum].state = TCP_STATE_TIMED_WAIT;								tcp_send_packet(buffer, socketnum, (TCP_ACK_FLAG), 0);								#if TCP_DEBUG								softuart_puts_progmem("FIN_WAIT2->TIMED_WAIT");								#endif							}							break;						///TIMED WAIT:						case(TCP_STATE_TIMED_WAIT):							#if TCP_DEBUG							softuart_puts_progmem("TIMED_WAIT: packet in ?! ");							#endif							break;						///CLOSING						case(TCP_STATE_CLOSING):							if (tcp_header_flags & TCP_ACK_FLAG){								tcp_sockets[socketnum].state = TCP_STATE_TIMED_WAIT;								#if TCP_DEBUG								softuart_puts_progmem("CLOSING->TIMED_WAIT");								#endif							}							break;						default:							#if TCP_DEBUG							softuart_puts_progmem("ERROR: invalid tcp state ! socket closed!");							#endif							tcp_close_socket(socketnum);					}					#if TCP_DEBUG					softuart_putnewline();					#endif					//we must set timed wait TTL here because timed wait is not packet triggered					if (tcp_sockets[socketnum].state == TCP_STATE_TIMED_WAIT){						tcp_sockets[socketnum].ttl = 5; //5 seconds timeout						#if TCP_DEBUG						softuart_puts_progmem("TIMED_WAIT: timeout set to 5s");						softuart_putnewline();						#endif					}					return;				}			}		}	}	//there is no active socket! -> conn request ?	if (tcp_header_flags == TCP_SYN_FLAG){		//yes, connection request. find a free socket:		socketnum = tcp_find_free_socket();		if (socketnum < TCP_SOCKET_COUNT){			//free socket found (:= socketnum) -> handle request			tcp_sockets[socketnum].state       = TCP_STATE_SYN_RECEIVED;			tcp_sockets[socketnum].source_port = source_port;			tcp_sockets[socketnum].source_ip   = source_ip;			tcp_sockets[socketnum].dest_port   = dest_port;					tcp_sockets[socketnum].ack         = nic_buffer_to_seq(&buffer[TCP_POS_SEQ])+1;			tcp_sockets[socketnum].seq         = 0;			tcp_sockets[socketnum].ttl         = TCP_TTL_TIMEOUT;			tcp_sockets[socketnum].misc_state  = 0;			//send SYN+ACK Packet			tcp_send_packet(buffer, socketnum, (TCP_SYN_FLAG|TCP_ACK_FLAG), 0);			//init seq counter:			tcp_sockets[socketnum].seq = 1;			//cleanup/initialise httpd connection:			httpd_cleanup_conn(socketnum);			#if TCP_DEBUG			softuart_puts_progmem("TCP : connection request. [OK]");			softuart_putnewline();			#endif			return;		}	}	/////////////////////////////////////////////////////	//if we get here something went wrong ...	// - we have no open socket for this packet	// - this is not an connection request	// - we have no more free sockets left (!)	//tcp_send_packet(buffer, socketnum, TCP_RST_FLAG, 0);//NO! WE HAVE NO SOCKNUM!	#if TCP_DEBUG	softuart_puts_progmem("TCP : WARN: ignoring packet (no socket open)");	softuart_putnewline();	#endif	return;}//called ~every second, removes dead tcp sockets// - decrement ttl (starts with TCP_TTL_TIMEOUT -> TCP_TTL_TIMEOUT seconds inactivity = timeout)// - if ttl==0 -> mark socket as closed !void tcp_ttl_cleanup(){	unsigned char i;	for(i=0; i<TCP_SOCKET_COUNT; i++){		//decrement ttl:		if (tcp_sockets[i].state != TCP_STATE_CLOSED){			tcp_sockets[i].ttl--;						//if socket TTL count is zero, close this socket!			if (tcp_sockets[i].ttl == 0){				tcp_close_socket(i);				#if TCP_DEBUG				softuart_puts_progmem("TCP : TTL timeout for socket [");				softuart_put_uint8(i);				softuart_puts_progmem("]. socket closed.");				softuart_putnewline();				#endif			}		}	}}void tcp_close_socket(unsigned char socketnum){	tcp_sockets[socketnum].state = TCP_STATE_CLOSED;	httpd_cleanup_conn(socketnum);}//send a tcp packet:void tcp_send_packet(unsigned char *buffer, unsigned char socketnum, unsigned char flags, unsigned int len){	unsigned int arp_idx;	unsigned int tmp;	unsigned long *ip;	if ((tcp_sockets[socketnum].source_ip & NIC_IP_NETMASK) != (nic_ip & NIC_IP_NETMASK)){		#if TCP_DEBUG		softuart_puts_progmem("TCP : ip ");		softuart_put_ip(tcp_sockets[socketnum].source_ip);		softuart_puts_progmem(" outside home net -> use gateway\r\n");		#endif		ip = &nic_gateway_ip;	}else{		ip = &tcp_sockets[socketnum].source_ip;	}	arp_idx = arp_search_by_ip(*ip);	if (arp_idx == -1){		//target ip (gateway) unknown				#if TCP_DEBUG		softuart_puts_progmem("TCP : ERR ARP UKNWN: ");		softuart_put_ip(tcp_sockets[socketnum].source_ip);		#endif				//normal solution:		//arp_send_request(buffer, ip);		//return; //<- must be called again !!!		///FIXME		#if TCP_DEBUG		softuart_puts_progmem("-> calling arp'hack to add mac<->ip mapping");		softuart_putnewline();		#endif				//but we do not want to wait for arp request etc		//we received an ip packet and we did not touch the mac header etc yet!		//-> the source mac is still in buffer! -> use this !		arp_idx = arp_add_mac2ip(&buffer[ETHERNET_POS_SRC_MAC], tcp_sockets[socketnum].source_ip);	}	///softuart_puts_progmem("<tcp packet sent> ");		//generate ip packet:	ip_generate_packet(buffer, 		&(tcp_sockets[socketnum].source_ip), 		(arp_table[arp_idx].mac),		tcp_sockets[socketnum].dest_port,		tcp_sockets[socketnum].source_port,		IP_PROTOCOL_TCP,		20+len	);	//setup source port (our port)	buffer[TCP_POS_SRC_PORT+0] = (tcp_sockets[socketnum].dest_port)>>8;	buffer[TCP_POS_SRC_PORT+1] = (tcp_sockets[socketnum].dest_port) & 0xFF;	//setup destination port (client port)	buffer[TCP_POS_DST_PORT+0] = (tcp_sockets[socketnum].source_port)>>8;	buffer[TCP_POS_DST_PORT+1] = (tcp_sockets[socketnum].source_port) & 0xFF;	//setup seq nr: FIXME	nic_seq_to_buffer(&buffer[TCP_POS_SEQ], (tcp_sockets[socketnum].seq));	/*buffer[TCP_POS_SEQ+0] = 0x00;	buffer[TCP_POS_SEQ+1] = 0x00;	buffer[TCP_POS_SEQ+2] = 0x00;	buffer[TCP_POS_SEQ+3] = 0x00;*/	//setup ack nr: FIXME	nic_seq_to_buffer(&buffer[TCP_POS_ACK], (tcp_sockets[socketnum].ack));	//setup header offset	buffer[TCP_POS_DATA_OFFSET] = 0x05<<4;	//setup flags:	buffer[TCP_POS_HEADERFLAGS] = flags;		//setup window	buffer[TCP_POS_WINDOWSIZE+0] = (NIC_BUFFERSIZE-20-14)>>8;	buffer[TCP_POS_WINDOWSIZE+1] = (NIC_BUFFERSIZE-20-14)&0xFF;	//setup checksum -> set 0x0000, will be replaced later!	buffer[TCP_POS_CHECKSUM+0] = 0x00;	buffer[TCP_POS_CHECKSUM+1] = 0x00;	//setup urgend pointer (not used -> 0)	buffer[TCP_POS_URGENT_PTR+0] = 0x00;	buffer[TCP_POS_URGENT_PTR+1] = 0x00;	//calc checksum: we use some tricks to do it faster:	//step0: calculate checksum for pseudoheader (0x00 TYPE TCPLEN)	tmp = IP_PROTOCOL_TCP + 20 + len;	//step1: calculate checksum IP_SRC+IP_DST + TCP header&data	//       (-2*4 -> include the 8 bytes source+dest ip)	// -> we calculated the checksum over the "pseudoheder" and tcp header+data	tmp = nethelp_checksum(&buffer[TCP_POS_SRC_PORT-2*4], 20+2*4 + len, tmp);	//set checksum:	buffer[TCP_POS_CHECKSUM+0] = tmp>>8;	buffer[TCP_POS_CHECKSUM+1] = tmp & 0xFF;	//send packet	nic_send_packet(buffer, TCP_POS_URGENT_PTR+2+len);		}

⌨️ 快捷键说明

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