// Perform all processing to resolve a hostname to IP address. // Returns 1 for successful Name resolution, 0 otherwise uint8_t EtherShield::resolveHostname(uint8_t *buf, uint16_t buffer_size, uint8_t *hostname ) { uint16_t dat_p; int plen = 0; long lastDnsRequest = millis(); uint8_t dns_state = DNS_STATE_INIT; boolean gotAddress = false; uint8_t dnsTries = 3; // After 10 attempts fail gracefully so other action can be carried out while( !gotAddress ) { // handle ping and wait for a tcp packet plen = enc28j60PacketReceive(buffer_size, buf); dat_p=packetloop_icmp_tcp(buf,plen); // We have a packet // Check if IP data if (dat_p == 0) { if (client_waiting_gw() ) { // No ARP received for gateway continue; } // It has IP data if (dns_state==DNS_STATE_INIT) { dns_state=DNS_STATE_REQUESTED; lastDnsRequest = millis(); dnslkup_request(buf,hostname); continue; } if (dns_state!=DNS_STATE_ANSWER){ // retry every minute if dns-lookup failed: if (millis() > (lastDnsRequest + 60000L) ){ if( --dnsTries <= 0 ) return 0; // Failed to allocate address dns_state=DNS_STATE_INIT; lastDnsRequest = millis(); } // don't try to use client before // we have a result of dns-lookup continue; } } else { if (dns_state==DNS_STATE_REQUESTED && udp_client_check_for_dns_answer( buf, plen ) ){ dns_state=DNS_STATE_ANSWER; //client_set_wwwip(dnslkup_getip()); client_tcp_set_serverip(dnslkup_getip()); gotAddress = true; } } } return 1; }
// prepare the webpage by writing the data to the tcp send buffer uint16_t print_webpage(uint8_t *buf) { uint16_t plen; char vstr[15]; plen=http200ok(); plen=fill_tcp_data_p(buf,plen,PSTR("<a href=/>[refresh]</a>")); plen=fill_tcp_data_p(buf,plen,PSTR("<h2>identi.ca notification status</h2>\n<pre>\n")); if (client_waiting_gw()){ plen=fill_tcp_data_p(buf,plen,PSTR("waiting for GW IP to answer arp.\n")); return(plen); } if (dns_state==1){ plen=fill_tcp_data_p(buf,plen,PSTR("waiting for DNS answer.\n")); return(plen); } /* // debug plen=fill_tcp_data_p(buf,plen,PSTR("\nweb IP:\n")); mk_net_str(vstr, dnslkup_getip() ,4,'.',10); plen=fill_tcp_data(buf,plen,vstr); plen=fill_tcp_data_p(buf,plen,PSTR("\n")); */ plen=fill_tcp_data_p(buf,plen,PSTR("Num of PD6 to GND connections: ")); // convert number to string: itoa(contact_onoff_cnt,vstr,10); plen=fill_tcp_data(buf,plen,vstr); plen=fill_tcp_data_p(buf,plen,PSTR("\nNum of identi.ca attempts: ")); // convert number to string: itoa(web_client_attempts,vstr,10); plen=fill_tcp_data(buf,plen,vstr); plen=fill_tcp_data_p(buf,plen,PSTR("\nNum successful identi.ca: ")); // convert number to string: itoa(web_client_sendok,vstr,10); plen=fill_tcp_data(buf,plen,vstr); plen=fill_tcp_data_p(buf,plen,PSTR("\nDate of last identi.ca: ")); plen=fill_tcp_data(buf,plen,datebuf); plen=fill_tcp_data_p(buf,plen,PSTR("\nTwitter notify is: ")); if (start_web_client==4){ plen=fill_tcp_data_p(buf,plen,PSTR("OFF")); }else{ plen=fill_tcp_data_p(buf,plen,PSTR("ON")); } plen=fill_tcp_data_p(buf,plen,PSTR("\n<form action=/ method=get>\npassw: <input type=password size=8 name=pw><input type=hidden name=mn ")); if (start_web_client==4){ plen=fill_tcp_data_p(buf,plen,PSTR("value=1><input type=submit value=\"enable identi.ca msg\">")); }else{ plen=fill_tcp_data_p(buf,plen,PSTR("value=0><input type=submit value=\"disable identi.ca msg\">")); } plen=fill_tcp_data_p(buf,plen,PSTR("</form>\n</pre><br><hr>tuxgraphics.org")); return(plen); }
int main(void){ uint16_t dat_p,plen; int8_t cmd; // Set the clock speed to "no pre-scaler" (8MHz with internal osc or // full external speed) // set the clock prescaler. First write CLKPCE to enable setting // of clock the next four instructions. // Note that the CKDIV8 Fuse determines the initial // value of the CKKPS bits. CLKPR=(1<<CLKPCE); // change enable CLKPR=0; // "no pre-scaler" _delay_loop_1(0); // 60us /*initialize enc28j60*/ enc28j60Init(mymac); enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz _delay_loop_1(0); // 60us /* Magjack leds configuration, see enc28j60 datasheet, page 11 */ // LEDB=yellow LEDA=green // // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10); enc28j60PhyWrite(PHLCON,0x476); DDRB|= (1<<DDB1); // LED, enable PB1, LED as output LEDOFF; DDRD&= ~(1<<DDD6); // enable PB6, as input PORTD|= (1<<PIND6); // internal pullup resistor on init_cnt2(); sei(); //init the web server ethernet/ip layer: init_ip_arp_udp_tcp(mymac,myip,MYWWWPORT); // init the web client: client_set_gwip(gwip); // e.g internal IP of dsl router // while(1){ // handle ping and wait for a tcp packet plen=enc28j60PacketReceive(BUFFER_SIZE, buf); dat_p=packetloop_icmp_tcp(buf,plen); if(plen==0){ // we are idle here if (client_waiting_gw() ){ continue; } if (dns_state==0){ sec=0; dns_state=1; dnslkup_request(buf,PSTR(WEBSERVER_VHOST)); continue; } if (dns_state==1 && dnslkup_haveanswer()){ dns_state=2; client_set_wwwip(dnslkup_getip()); } if (dns_state!=2){ // retry every minute if dns-lookup failed: if (sec > 60){ dns_state=0; } // don't try to use web client before // we have a result of dns-lookup continue; } //---------- if (start_web_client==1){ LEDON; start_web_client=2; sec=0; web_client_attempts++; // the identi.ca line is status=Url_encoded_string strcat(statusstr,"status="); // the text to send to identi.ca (append after status=): //urlencode("Meals are ready",&(statusstr[7])); urlencode("I like tuxgraphics eth boards, ",&(statusstr[7])); // append a number: itoa(web_client_attempts,&(statusstr[strlen(statusstr)]),10); // The BLOGGACCOUNT Authorization code can be generated from // username and password of your identi.ca account // by using this encoder: http://tuxgraphics.org/~guido/javascript/base64-javascript.html client_http_post(PSTR("/api/statuses/update.xml"),PSTR(WEBSERVER_VHOST),PSTR(BLOGGACCOUNT),statusstr,&browserresult_callback); } // count how often the switch was triggered at all: if (contact_debounce==0 && bit_is_clear(PIND,PIND6)){ contact_onoff_cnt++; contact_debounce=1; } // we send only a request if we are in the right state (do // not flood with request): if (start_web_client==0 && bit_is_clear(PIND,PIND6)){ resend=1; // resend once if it failed start_web_client=1; } // Reset after a delay of 3 min to prevent email sending. // We reset only if the contact on PD6 was released. if (start_web_client<=3 && sec==180 && !bit_is_clear(PIND,PIND6)){ start_web_client=0; } // Resend the message if it failed: if (start_web_client==2 && sec==7 && resend){ start_web_client=1; resend--; } continue; } if(dat_p==0){ // plen!=0 // check for incomming messages not processed // as part of packetloop_icmp_tcp, e.g udp messages udp_client_check_for_dns_answer(buf,plen); 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 dat_p=http200ok(); dat_p=fill_tcp_data_p(buf,dat_p,PSTR("<h1>200 OK</h1>")); goto SENDTCP; } cmd=analyse_get_url((char *)&(buf[dat_p+4])); // for possible status codes see: // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html if (cmd==-1){ dat_p=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 401 Unauthorized\r\nContent-Type: text/html\r\n\r\n<h1>401 Unauthorized</h1>")); goto SENDTCP; } if (cmd==1 && start_web_client==4){ // email was off, switch on start_web_client=0; } if (cmd==0 ){ start_web_client=4; // email off } dat_p=http200ok(); dat_p=print_webpage(buf); // SENDTCP: www_server_reply(buf,dat_p); // send data } return (0); }
uint8_t EtherShield::ES_client_waiting_gw() { return( client_waiting_gw() ); }