1 /* Arduino Projekt aus der Beispielsammlung http://www.nuelectronics.com/download/projects/etherShield.zip
2
3 */
4
5 //extern "C" void __cxa_pure_virtual(void); //for C++ defines
6 //void __cxa_pure_virtual(void) {;
7
8 #pragma GCC diagnostic ignored "-Wwrite-strings"
9
10 #include "WProgram.h" //import main Arduino header file
11
12 #include "EncEthernet.h"
13
14 // change MAC and IP address if necessary
15 static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x24};
16 static uint8_t myip[4] = {192,168,0,15};
17 static char baseurl[]="http://192.168.0.15/";
18 static uint16_t mywwwport =80;
19
20 #define BUFFER_SIZE 500
21 static uint8_t buf[BUFFER_SIZE+1];
22 #define STR_BUFFER_SIZE 22
23 static char strbuf[STR_BUFFER_SIZE+1];
24
25 EncEthernet es = EncEthernet();
26
27 // prepare the webpage by writing the data to the tcp send buffer
28 uint16_t print_webpage(uint8_t *buf);
29 int8_t analyse_cmd(char *str);
30 int main(){
31 setup();
32 loop();
33 }
34 void setup(){
35
36 /*initialize enc28j60*/
37 es.E_enc28j60Init(mymac);
38 es.E_enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz
39 delay(10);
40
41 /* Magjack leds configuration, see enc28j60 datasheet, page 11 */
warum sind in diesem Beispiel die Bits 12-13 nicht auf 1???
42 // LEDA=greed LEDB=yellow
43
Wie die Leds angeschlossen sind entscheidet über full oder half duplex
44 // 0x880 is PHLCON LEDB=on, LEDA=on
45 // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00);
46 es.E_enc28j60PhyWrite(PHLCON,0x880);
47 delay(500);
48
49 // 0x990 is PHLCON LEDB=off, LEDA=off
50 // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00);
51 es.E_enc28j60PhyWrite(PHLCON,0x990);
52 delay(500);
53
54 // 0x880 is PHLCON LEDB=on, LEDA=on
55 // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00);
56 es.E_enc28j60PhyWrite(PHLCON,0x880);
57 delay(500);
58
59 // 0x990 is PHLCON LEDB=off, LEDA=off
60 // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00);
61 es.E_enc28j60PhyWrite(PHLCON,0x990);
62 delay(500);
63
64 // 0x476 is PHLCON LEDA=links status, LEDB=display receive/transmit activity
65 // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10);
66 es.E_enc28j60PhyWrite(PHLCON,0x476);
67 delay(100);
68
69 //init the ethernet/ip layer:
70 es.E_init_ip_arp_udp_tcp(mymac,myip,mywwwport);
71 }
72
73 void loop(){
74 uint16_t plen, dat_p;
75 int8_t cmd;
76
77 plen = es.E_enc28j60PacketReceive(BUFFER_SIZE, buf);
78 // plen will ne unequal to zero if there is a valid packet
79 if(plen!=0){
Arp liefert für eine gesuchte IP-Adresse die zugehörige MAC-Adresse; hier: der Router sucht die Mac-Adresse des Shields und stellt daher eine ARP-Anfrage ins Netz
80 // arp is broadcast if unknown but a host may also verify
81 // the mac address by sending it to a unicast address.
82 if(es.E_eth_type_is_arp_and_my_ip(buf,plen)){
83 es.E_make_arp_answer_from_request(buf);
84 return;
85 }
86
falsche IP-Adresse => Paket verwerfen
87 // check if ip packets are for us:
88 if(es.E_eth_type_is_ip_and_my_ip(buf,plen)==0){
89 return;
90 }
91
Reaktion auf einen PING Pakettyp: ICMP Paket Typ: Echorequest Typen: siehe net.h
92 if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V
93 && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){
94 es.E_make_echo_reply_from_request(buf,plen);
95 return;
96 }
97
TCP fragt nach den Portnummern: diese sind 16bit ACHTUNG: hier ist das höhere Byte NULL
98 // tcp port www start, compare only the lower byte
99 if (buf[IP_PROTO_P]==IP_PROTO_TCP_V
100 && buf[TCP_DST_PORT_H_P]== 0
101 && buf[TCP_DST_PORT_L_P]== mywwwport){
TCP-Flags http://en.wikipedia.org/wiki/Transmission_Control_Protocol
102 if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V){
TCP Verbindungsaufbau
103 // make_tcp_synack_from_syn does already send the syn,ack
104 es.E_make_tcp_synack_from_syn(buf);
105 return;
106 }
ACK empfangen ==> Paket im Puffer buf
107 if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V){
108
es.E_init_len_info(buf);
//
init some data structures necessary
for the following operation
109
dat_p=es.E_get_tcp_data_pointer();
//get a pointer to the start of
tcp data in buf
110 if (dat_p==0){ // we can possibly have no data, just ack:
111 if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V){
112 es.E_make_tcp_ack_from_any(buf);
113 }
114 return;
115 }
die Daten liegen ab der Stelle dat_p im Puffer (char*)&(buf[dat_p]) ist ein Pointer auf den Start der Daten
116 if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){
117 // head, post and other methods for possible status codes
118 // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
eine Get-Anfrage wird sofort positiv bestätigt
119 plen=es.E_fill_tcp_data_p(buf, 0, PSTR("HTTP/1.0 200 OK-Type: text/html<h1>200 OK</h1>"));
120 goto SENDTCP;
121 }
122 if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0){
123 plen=print_webpage(buf);
124 goto SENDTCP;
125 }
126 cmd=analyse_cmd((char *)&(buf[dat_p+5]));
127 if (cmd==1){
128 plen=print_webpage(buf);
129 }
if (cmd==2) plen=print_webpage1(buf) usw...
130 // send ack for http get
131 SENDTCP: es.E_make_tcp_ack_from_any(buf);
132 // send data
133 es.E_make_tcp_ack_with_data(buf,plen);
134 }
135 }
136 }
137 }
138
139 // The returned value is stored in the global var strbuf
140 uint8_t find_key_val(char *str,char *key)
141 {
142 uint8_t found=0;
143 uint8_t i=0;
144 char *kp;
145 kp=key;
146 while(*str && *str!=' ' && found==0){
147 if (*str == *kp){
148 kp++;
149 if (*kp == '0'){
150 str++;
151 kp=key;
152 if (*str == '='){
153 found=1;
154 }
155 }
156 }else{
157 kp=key;
158 }
159 str++;
160 }
161 if (found==1){
162 // copy the value to a buffer and terminate it with '0'
163 while(*str && *str!=' ' && *str!='&' && i<STR_BUFFER_SIZE){
164 strbuf[i]=*str;
165 i++;
166 str++;
167 }
168 strbuf[i]='0';
169 }
170 return(found);
171 }
172
173 int8_t analyse_cmd(char *str)
174 {
175 int8_t r=-1;
176
177 if (find_key_val(str,"cmd")){
178 if (*strbuf < 0x3a && *strbuf > 0x2f){
179 // is a ASCII number, return it
180 r=(*strbuf-0x30);
181 }
182 }
183 return r;
184 }
185
186
187 uint16_t print_webpage(uint8_t *buf)
188 {
189 uint16_t plen;
190 plen=es.E_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK-Type: text/html"));
191 plen=es.E_fill_tcp_data_p(buf,plen,PSTR("<center><p><h1>Welcome to Arduino Ethernet Shield V1.0</h1></p> "));
192 plen=es.E_fill_tcp_data_p(buf,plen,PSTR("<hr><br> <h2><font color="blue">-- Your Arduino is online now -- "));
193 plen=es.E_fill_tcp_data_p(buf,plen,PSTR("<br> Control digital outputs "));
194 plen=es.E_fill_tcp_data_p(buf,plen,PSTR("<br> Read digital analog inputs HERE "));
195 plen=es.E_fill_tcp_data_p(buf,plen,PSTR(" <br></font></h2> ") );
196 plen=es.E_fill_tcp_data_p(buf,plen,PSTR("</center><hr> <a href="http://www.flamingoeda.com">www.flamingoeda.com<a>"));
197
198 return(plen);
199 }
Kner
2011