ENC28J60提供的超小协议栈,它用一个全局的数组来做接收和发送缓冲。部分发送数据包从接收包中更改标志和校验和得到,最大化的减少内存拷贝。实现TCP/IP协议收发数据包的各个子功能,如校验和计算,标志填充,包头填充等,但是要求用户应用层程序自行组包解包,要求程序员更加深入的了解TCP/IP协议,是学习的好资料。
以下是典型应用主程序
void main(void)
{
uint8_t data i=0;
uint16_t data j=0;
uint16_t data plen=0;
uint16_t data dat_p=0;
uint32_t data dat_p_post;
uint8_t data cmd_pos=0;
uint8_t data payloadlen=0;
char temp[100];
// char str[30];
// char cmdval;
int data post_succeed;
// int write_succeed;
// int read_succeed;
// int eeprom_succeed;
//System_Hardware_Init:
InitHardware(); //硬件初始化
SBUF=0xEF;
_delay_ms(20);
// Create_PPPOE(buf);//建立PPPOE连接
while(1){
// get the next new packet:
WDT_CONTR=0x3C;//00111100//1.1S@11.0592MHz//初始化看门狗fosc/32,2s溢出@6MHZ
plen = enc28j60PacketReceive(BUFFER_SIZE, buf);//1500
/*plen will ne unequal to zero if there is a valid
* packet (without crc error) */
if(plen==0)
continue; // "no data"
// "Get one"
// arp is broadcast if unknown but a host may also
// verify the mac address by sending it to
// a unicast address.
if((buf[ETH_TYPE_H_P]==ETHTYPE_PPPOE_SESS_H_V)&&(buf[ETH_TYPE_L_P]==ETHTYPE_PPPOE_SESS_L_V))//SESSION//8864
if(PPP_LCP_V==(buf[PPP_PROTOCOL_H_P]<<8|buf[PPP_PROTOCOL_L_P]))//PPP_LCP协议
if(PPP_ECHO_REQ_V==buf[PPP_CODE_P])//回应远程主机的ECHO查询
{
make_ECHO_REPLAY_FROM_REQ(buf);
UART1_PutNormalStr("echo reply.\r\n");
}
//if(eth_type_is_arp_and_my_ip(buf,plen))
//{
//UART1_PutStr(buf,plen);//过交换机接收正确
//if(eth_type_is_arp_req(buf))
//{
// make_arp_answer_from_request(buf); // make arp answer from request
//UART1_PutStr(buf,plen);//过交换机发送正确
//}
//continue;
//}
// arp is broadcast if unknown but a host may also
// verify the mac address by sending it to
// a unicast address.
if(eth_type_is_arp_and_my_ip(buf,plen)) {
if(eth_type_is_arp_req(buf))
make_arp_answer_from_request(buf);
continue;
}
// check if ip packets are for us:
if(eth_type_is_ip_and_my_ip(buf,plen)==0)
continue;
// led----------
// a ping packet, let's send pong
if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V)
{
make_echo_reply_from_request(buf,plen);
continue;
}
// tcp port www start, compare only the lower byte
if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==MYWWWPORT)
{
if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V)
{
make_tcp_synack_from_syn(buf); // make_tcp_synack_from_syn does already send the syn,ack
continue;
}
if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V)
{
init_len_info(buf); // init some data structures, we can possibly have no data, just ack:
dat_p=get_tcp_data_pointer();
if (dat_p==0)
{
if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V) // finack, answer with ack
make_tcp_ack_from_any(buf);
// just an ack with no data, wait for next packet
continue;
}
/*************************** POST Module ********************************/
if (strncmp("POST ",(char *)&(buf[dat_p]),5)==0)
{
UART1_PutNormalStr( str_uart1_post );
UART1_PutNormalStr( buf+dat_p );
if( strncmp( "/ipctrl ", (char *)&(buf[dat_p+5]), 8 ) == 0 )
{
dat_p_post = find_ip_information( (char *)&(buf[dat_p]) );
UART1_PutNormalStr( buf+dat_p+dat_p_post );
post_succeed = ip_refresh( buf+dat_p+dat_p_post );
if( post_succeed == 0 ); // 上传成功,-1为操作失败,1为无变化
{
UART1_PutNormalStr( New_NET );
// eeprom_succeed = save_ip_2_eeprom();
// if( eeprom_succeed == 4)
// goto System_Hardware_Init;
}
plen=webpage_ipctrl(buf);
}
else if( strncmp( "/IPG ", (char *)&(buf[dat_p+5]), 5 ) == 0 )
{
dat_p_post = find_useful_information( (char *)&(buf[dat_p]) );
UART1_PutNormalStr( buf+dat_p+dat_p_post );
post_succeed = members_refresh( buf+dat_p+dat_p_post );
if( post_succeed == 0 ); // 0为上传成功,开始写入下位机
// write_succeed = Uart_write();
// read_succeed = Uart_read(); // 不管是否写入新参数,都读取
plen=webpage_IPG(buf);
}
goto SENDTCP;
}
/******************************** GET Module ********************************/
else if (strncmp("GET ",(char *)&(buf[dat_p]),4)==0)
{
UART1_PutNormalStr( str_uart1_get );
UART1_PutNormalStr( buf+dat_p );
if( strncmp( "/ipctrl ", (char *)&(buf[dat_p+4]), 8 ) == 0 )
plen=webpage_ipctrl(buf);
else if( strncmp( "/IPG ", (char *)&(buf[dat_p+4]), 5 ) == 0 )
{
// read_succeed = Uart_read(); // 读取下位机最新信息
// if( read_succeed == 0 )
plen=webpage_IPG(buf);
}
else if( strncmp( "/ ", (char *)&(buf[dat_p+4]), 2 ) == 0 )
//plen=webpage_index(buf);
plen=fill_tcp_data( buf, 0, webpage_index );
else
{
sprintf(temp,"HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n");
plen=fill_tcp_data( buf, 0, temp );
sprintf(temp,"<p>Usage: http://host_or_ip/pagename</p>\n");
plen=fill_tcp_data( buf, plen, temp );
//plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n"));
//plen=fill_tcp_data_p(buf,plen,PSTR("<p>Usage: http://host_or_ip/pagename</p>\n"));
}
goto SENDTCP;
}
SENDTCP:
make_tcp_ack_from_any(buf); // send ack for http get
make_tcp_ack_with_data(buf,plen); // send data
continue;
}
}
// tcp port www end
//
// udp start, we listen on udp port 1200=0x4B0
/*
if (buf[IP_PROTO_P]==IP_PROTO_UDP_V&&buf[UDP_DST_PORT_H_P]==4&&buf[UDP_DST_PORT_L_P]==0xb0)
{
payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN;
// you must sent a string starting with v
// e.g udpcom version 10.0.0.24
if (verify_password((char *)&(buf[UDP_DATA_P])))
{
// find the first comma which indicates
// the start of a command:
cmd_pos=0;
while(cmd_pos<payloadlen)
{
cmd_pos++;
if (buf[UDP_DATA_P+cmd_pos]==',')
{
cmd_pos++; // put on start of cmd
break;
}
}
// a command is one char and a value. At
// least 3 characters long. It has an '=' on
// position 2:
if (cmd_pos<2 || cmd_pos>payloadlen-3 || buf[UDP_DATA_P+cmd_pos+1]!='=')
{
strcpy(str,"e=no_cmd");
goto ANSWER;
}
// supported commands are
// t=1 t=0 t=?
if (buf[UDP_DATA_P+cmd_pos]=='t')
{
cmdval=buf[UDP_DATA_P+cmd_pos+2];
if(cmdval=='1')
{ // transistor on
IOCLR0 = LED;
strcpy(str,"t=1");
goto ANSWER;
}
else if(cmdval=='0')
{ // transistor off
IOSET0 = LED;
strcpy(str,"t=0");
goto ANSWER;
}
else if(cmdval=='?')
{
if (IOPIN0 & LED)
{
strcpy(str,"t=1");
goto ANSWER;
}
strcpy(str,"t=0");
goto ANSWER;
}
}
strcpy(str,"e=no_such_cmd");
goto ANSWER;
}
strcpy(str,"e=invalid_pw");
ANSWER:
make_udp_reply_from_request(buf,str,strlen(str),MYUDPPORT);
}
*/
}
_delay_ms(200);//
//return;
}//end main
文章评论(0条评论)
登录后参与讨论