#include #include "enc28j60.h" #include "ip_arp_udp_tcp.h" #include "net.h" #include "hal.h" #include "led.h" //#include "uart.h" #include "simple_server.h" #include "general_type.h" #include "temp.h" #define PSTR(s) s unsigned char i_1=0,i_2=0,i_3=0,i_4=0; unsigned char led1=0,led2=0,led3=0,led4=0,led=0; unsigned char temp[]={"0123456789ABCDEF"}; unsigned char temp1[]={"0123456789"}; u16 temp_1; unsigned char temp_2[5]; unsigned char temp_3[7]; //extern void delay_ms(unsigned char ms); // please modify the following two lines. mac and ip have to be unique // in your local area network. You can not have the same numbers in // two devices: static unsigned char mymac[6] = {0x04,0x02,0x35,0x00,0x00,0x01}; //static unsigned char myip[4] = {192,168,0,100}; // base url (you can put a DNS name instead of an IP addr. if you have // a DNS server (baseurl must end in "/"): static unsigned int mywwwport =80; // listen port for tcp/www (max range 1-254) // or on a different port: //static char baseurl[]="http://10.0.0.24:88/"; //static unsigned int mywwwport =88; // listen port for tcp/www (max range 1-254) // static unsigned int myudpport =1200; // listen port for udp // how did I get the mac addr? Translate the first 3 numbers into ascii is: TUX #define BUFFER_SIZE 1500//400 static unsigned char buf[BUFFER_SIZE+1]; static unsigned char BUF; // the password string (only the first 5 char checked), (only a-z,0-9,_ characters): static char password[]="123456"; // must not be longer than 9 char #define LED1_ON() LED1_RUN(1); #define LED2_ON() LED2_RUN(1); #define LED3_ON() LED3_RUN(1); #define LED4_ON() LED4_RUN(1); #define LED1_OFF() LED1_RUN(0); #define LED2_OFF() LED2_RUN(0); #define LED3_OFF() LED3_RUN(0); #define LED4_OFF() LED4_RUN(0); // unsigned char verify_password(char *str) { // the first characters of the received string are // a simple password/cookie: //用 法: int strncmp(char *str1, char *str2, int maxlen);    //说明:比较字符串str1和str2的大小,如果str1小于str2,返回值就<0,反之如果str1大于str2,返回值就>0, //如果str1等于str2,返回值就=0,maxlen指的是str1与str2的比较的字符数。 //此函数功能即比较字符串str1和str2的前maxlen个字符。 if (strncmp(password,str,5)==0) { return(1); } return(0); } // takes a string of the form password/commandNumber and analyse it // return values: -1 invalid password, otherwise command number // -2 no command given but password valid unsigned char analyse_get_url(char *str) { unsigned char i=0; if (verify_password(str)==0) //判断密码是否正确,函数返回0说明密码正确即verify_password(str)==0 { return(-1); ////当验证是密码且是正确时就将-1返回跳出函数,不是密码或者密码错误就往下执行 } // find first "/" // passw not longer than 9 char: while(*str && i<10 && *str >',' && *str<'{') { if (*str=='/') { str++; break; } i++; str++; } if (*str < 0x3a && *str > 0x2f) //当是ASCII码时将其返回 { // is a ASCII number, return it return(*str-0x30); } return(-2); } // prepare the webpage by writing the data to the tcp send buffer /********************************************************************** 功能:打印页面代码 ***********************************************************************/ unsigned int print_webpage(unsigned char *buf,unsigned char on_off1,unsigned char on_off2,unsigned char on_off3,unsigned char on_off4) { unsigned int plen,j; unsigned char macmac[17]; plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n")); plen=fill_tcp_data_p(buf,plen,PSTR(""));//页面开始处 plen=fill_tcp_data_p(buf,plen,PSTR("
"));//页面开始处 plen=fill_tcp_data_p(buf,plen,PSTR("
基于STM32的以太网通信系统设计

")); plen=fill_tcp_data_p(buf,plen,PSTR("系统资源:STM32F103RBT6,128K Flash, 64K SRAM

")); plen=fill_tcp_data_p(buf,plen,PSTR("嵌入式服务器IP:192.168.1.100 MAC:04-02-35-00-00-01

")); plen=fill_tcp_data_p(buf,plen,PSTR("

关闭LED1:")); plen=fill_tcp_data_p(buf,plen,PSTR(" LED1亮
")); } else if (led1==0x35|led1==0) { plen=fill_tcp_data_p(buf,plen,PSTR("1>点亮LED1:")); plen=fill_tcp_data_p(buf,plen,PSTR(" LED1灭")); } plen=fill_tcp_data_p(buf,plen,PSTR("

关闭LED2:")); plen=fill_tcp_data_p(buf,plen,PSTR(" LED2亮
")); } else if(led2==0x36|led2==0) { plen=fill_tcp_data_p(buf,plen,PSTR("2>点亮LED2:")); plen=fill_tcp_data_p(buf,plen,PSTR(" LED2灭")); } plen=fill_tcp_data_p(buf,plen,PSTR("

关闭LED3:")); plen=fill_tcp_data_p(buf,plen,PSTR(" LED3亮
")); } else if(led3==0x37|led3==0) { plen=fill_tcp_data_p(buf,plen,PSTR("3>点亮LED3:")); plen=fill_tcp_data_p(buf,plen,PSTR(" LED3灭")); } plen=fill_tcp_data_p(buf,plen,PSTR("

关闭LED4:")); plen=fill_tcp_data_p(buf,plen,PSTR(" LED4亮
")); } else if(led4==0x38|led4==0) { plen=fill_tcp_data_p(buf,plen,PSTR("4>点亮LED4:")); plen=fill_tcp_data_p(buf,plen,PSTR(" LED4灭")); } plen=fill_tcp_data_p(buf,plen,PSTR("
STM32内部温度传感器温度: ")); plen=fill_tcp_data_p(buf,plen,PSTR(temp_2)); plen=fill_tcp_data_p(buf,plen,"°C
"); plen=fill_tcp_data_p(buf,plen,PSTR("


宇运电子
")); plen=fill_tcp_data_p(buf,plen,PSTR("

世界触手可及 一切皆有可能
")); plen=fill_tcp_data_p(buf,plen,"
想了解更多登入官方淘宝店:http://mcu-web.taobao.com
"); plen=fill_tcp_data_p(buf,plen,PSTR("
您电脑本地IP地址:")); plen=fill_tcp_data_p(buf,plen,PSTR(tempfwip)); plen=fill_tcp_data_p(buf,plen,PSTR(" 您电脑网卡物理地址:")); for(j=0;j<17;j++) macmac[j]=tempfwmac[j]; plen=fill_tcp_data_p(buf,plen,PSTR(macmac)); plen=fill_tcp_data_p(buf,plen,"
"); plen=fill_tcp_data_p(buf,plen,PSTR("")); ////页面结束 return(plen); } unsigned int simple_server(void) { unsigned int plen,i1=0; unsigned int dat_p; unsigned char ii; unsigned char cmd,*buf1; unsigned int payloadlen=0; LED1_ON(); LED2_ON(); LED3_ON(); LED4_ON(); plen = enc28j60getrev(); /*initialize enc28j60*/ enc28j60Init(mymac); // ENC28J60_Init(mymac); //把IP地址和MAC地址写入各自的缓存区 ipaddr[] macaddr[] init_ip_arp_udp_tcp(mymac,myip,mywwwport); //指示灯状态:0x476 is PHLCON LEDA(绿)=links status, LEDB(红)=receive/transmit //enc28j60PhyWrite(PHLCON,0x7a4); //PHLCON:PHY 模块LED 控制寄存器 enc28j60PhyWrite(PHLCON,0x0476); enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz //init the ethernet/ip layer: while(1) { get_temperature(&temp_1); temp_2[0]=temp1[temp_1/100]; temp_2[1]=temp1[temp_1%100/10]; temp_2[2]='.'; temp_2[3]=temp1[temp_1%10]; //°C plen=0; plen = enc28j60PacketReceive(BUFFER_SIZE, buf); /*plen will ne unequal to zero if there is a valid packet (without crc error) */ if(plen==0) { continue; } // arp is broadcast if unknown but a host may also // verify the mac address by sending it to // a unicast address. //ARP 帧包发送 42 if(eth_type_is_arp_and_my_ip(buf,plen)) { 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; } if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V) { // a ping packet, let's send pong PING的回应 make_echo_reply_from_request(buf, plen); /*获取mac地址*/ for(ii=0;ii<6;ii++) { fwmac[ii]=buf[ii]; tempfwmac[ii*3+0]=temp[fwmac[ii]/16]; tempfwmac[ii*3+1]=temp[fwmac[ii]%16]; if(ii<5) tempfwmac[ii*3+2]='-'; } /*获取ip地址*/ for(ii=0;ii<4;ii++) { fwip[ii]=buf[ii+30];//0xbf tempfwip[ii*4+0]=temp1[fwip[ii]/100]; //temp1[]={"0123456789"}; tempfwip[ii*4+1]=temp1[fwip[ii]%100/10]; tempfwip[ii*4+2]=temp1[fwip[ii]%100%10]; if(ii<3) tempfwip[ii*4+3]='.'; } 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) { /*获取mac地址*/ for(ii=0;ii<6;ii++) { fwmac[ii]=buf[ii+6]; tempfwmac[ii*3+0]=temp[fwmac[ii]/16]; tempfwmac[ii*3+1]=temp[fwmac[ii]%16]; if(ii<5) tempfwmac[ii*3+2]='-'; } /*获取ip地址*/ iptemp[0]=buf[30]; iptemp[1]=buf[27]; iptemp[2]=buf[28]; iptemp[3]=buf[29]; for(ii=0;ii<4;ii++) { fwip[ii]=iptemp[ii]; tempfwip[ii*4+0]=temp1[fwip[ii]/100]; tempfwip[ii*4+1]=temp1[fwip[ii]%100/10]; tempfwip[ii*4+2]=temp1[fwip[ii]%100%10]; if(ii<3) tempfwip[ii*4+3]='.'; } 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; } if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0) { // head, post and other methods: // for possible status codes see: // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n

200 OK

")); goto SENDTCP; } if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0) { 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("
"));//页面开始处 plen=fill_tcp_data_p(buf,plen,PSTR("
密码:

")); plen=fill_tcp_data_p(buf,plen,PSTR("
")); plen=fill_tcp_data_p(buf,plen,PSTR("
")); ////页面结束 goto SENDTCP; } if(strncmp("/?mm=654321",(char *)&(buf[dat_p+4]),11)!=0) { if(strncmp("/?led",(char *)&(buf[dat_p+4]),5)==0) goto SENDTCP1; 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("
"));//页面开始处 plen=fill_tcp_data_p(buf,plen,PSTR("
密码:

")); plen=fill_tcp_data_p(buf,plen,PSTR("




")); plen=fill_tcp_data_p(buf,plen,PSTR("
密码错误请重新输入!!

")); plen=fill_tcp_data_p(buf,plen,PSTR("
")); ////页面结束 goto SENDTCP; } SENDTCP1: cmd=analyse_get_url((char *)&(buf[dat_p+10])); BUF=buf[64]; cmd=BUF; if (cmd==-1) { plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 401 Unauthorized\r\nContent-Type: text/html\r\n\r\n

401 Unauthorized

")); goto SENDTCP; } if (cmd==0x31) { LED1_OFF(); led1=i_1=0x31; } else if(cmd==0x35) { LED1_ON(); led1=i_1=0x35; } if (cmd==0x32) { LED2_OFF(); led2=i_2=0x32; } else if(cmd==0x36) { LED2_ON(); led2=i_2=0x36; } if (cmd==0x33) { LED3_OFF(); led3=i_3=0x33; } else if(cmd==0x37) { LED3_ON(); led3=i_3=0x37; } if (cmd==0x34) { LED4_OFF(); led4=i_4=0x34; } else if(cmd==0x38) { LED4_ON(); led4=i_4=0x38; } // if (cmd==-2) or any other value // just display the status: plen=print_webpage(buf,(i_1),(i_2),(i_3),(i_4)); ///////////////////////////////////////////////// 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_H_P]; payloadlen=payloadlen<<8; payloadlen=(payloadlen+buf[UDP_LEN_L_P])-UDP_HEADER_LEN; //payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN; ANSWER: //while(1){ for(i1=0; i1