// Perform all processing to get an IP address plus other addresses returned, e.g. gw, dns, dhcp server. // Returns 1 for successful IP address allocation, 0 otherwise uint8_t EtherShield::allocateIPAddress(uint8_t *buf, uint16_t buffer_size, uint8_t *mymac, uint16_t myport, uint8_t *myip, uint8_t *mynetmask, uint8_t *gwip, uint8_t *dnsip, uint8_t *dhcpsvrip ) { uint16_t dat_p; int plen = 0; long lastDhcpRequest = millis(); uint8_t dhcpState = 0; boolean gotIp = false; uint8_t dhcpTries = 10; // After 10 attempts fail gracefully so other action can be carried out dhcp_start( buf, mymac, myip, mynetmask,gwip, dnsip, dhcpsvrip ); while( !gotIp ) { // handle ping and wait for a tcp packet plen = enc28j60PacketReceive(buffer_size, buf); dat_p=packetloop_icmp_tcp(buf,plen); if(dat_p==0) { int retstat = check_for_dhcp_answer( buf, plen); dhcpState = dhcp_state(); // we are idle here if( dhcpState != DHCP_STATE_OK ) { if (millis() > (lastDhcpRequest + 10000L) ){ lastDhcpRequest = millis(); if( --dhcpTries <= 0 ) return 0; // Failed to allocate address // send dhcp dhcp_start( buf, mymac, myip, mynetmask,gwip, dnsip, dhcpsvrip ); } } else { if( !gotIp ) { gotIp = true; //init the ethernet/ip layer: init_ip_arp_udp_tcp(mymac, myip, myport); // Set the Router IP client_set_gwip(gwip); // e.g internal IP of dsl router // Set the DNS server IP address if required, or use default dnslkup_set_dnsip( dnsip ); } } } } return 1; }
void EtherShield::ES_client_set_gwip(uint8_t *gwipaddr) { client_set_gwip(gwipaddr); }
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); }
int main(void){ uint16_t dat_p; 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 client_set_wwwip(websrvip); // while(1){ // handle ping and wait for a tcp packet dat_p=packetloop_icmp_tcp(buf,enc28j60PacketReceive(BUFFER_SIZE, buf)); if(dat_p==0){ if (start_web_client==1){ LEDON; start_web_client=2; sec=0; web_client_attempts++; // the text to send in the body of the mail: urlencode("The door is open",urlvarstr); // The string "test+emailnotify" is the subject line // of the email. A plus sign translates into a space character. // The MMaccountID is gus123, edit and replace by your own. client_browse_url(PSTR("/cgi-bin/mm?a=gus123&s=test+emailnotify&d="),urlvarstr,PSTR(WEBSERVER_VHOST),&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 an email if we are in the right state (do // not flood with email): 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 email if it failed: if (start_web_client==2 && sec==7 && resend){ start_web_client=1; resend--; } 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); }
static void _eth_spi_handle_frame() { u16_t rx_stat; int plen = enc28j60PacketReceive(ETHSPI_MAX_PKT_SIZE, ethspi.rxbuf, &rx_stat); if (plen == 0) { DBG(D_ETH, D_DEBUG, "ethspi no frame, rx_stat:%04x\n", rx_stat); return; } #ifdef ETH_STATS ethspi.rx_frames++; ethspi.rx_data += plen; #endif DBG(D_ETH, D_DEBUG, "ethspi got frame, len %i, rx_stat:%04x\n", plen, rx_stat); //printbuf(ethspi.rxbuf, MIN(64, plen)); // doing dhcp, do not allow anything else right now if (ethspi.dhcp.query && ethspi.dhcp.active) { int dhcp_res; dhcp_res = check_for_dhcp_answer(ethspi.rxbuf, plen); DBG(D_ETH, D_DEBUG, "ethspi DHCP:%i state:%i\n", dhcp_res, dhcp_state()); if (dhcp_state() == DHCP_STATE_OK) { ethspi.dhcp.query = FALSE; DBG(D_ETH, D_DEBUG, "ethspi DHCP OK\n"); DBG(D_ETH, D_INFO, "ethspi DHCP ip %i.%i.%i.%i\n", ethspi.dhcp.ipaddr[0], ethspi.dhcp.ipaddr[1], ethspi.dhcp.ipaddr[2], ethspi.dhcp.ipaddr[3]); DBG(D_ETH, D_DEBUG, "ethspi DHCP gwip %i.%i.%i.%i\n", ethspi.dhcp.gwip[0], ethspi.dhcp.gwip[1], ethspi.dhcp.gwip[2], ethspi.dhcp.gwip[3]); DBG(D_ETH, D_DEBUG, "ethspi DHCP mask %i.%i.%i.%i\n", ethspi.dhcp.mask[0], ethspi.dhcp.mask[1], ethspi.dhcp.mask[2], ethspi.dhcp.mask[3]); DBG(D_ETH, D_DEBUG, "ethspi DHCP dhcp %i.%i.%i.%i\n", ethspi.dhcp.dhcp_server[0], ethspi.dhcp.dhcp_server[1], ethspi.dhcp.dhcp_server[2], ethspi.dhcp.dhcp_server[3]); DBG(D_ETH, D_DEBUG, "ethspi DHCP dns %i.%i.%i.%i\n", ethspi.dhcp.dns_server[0], ethspi.dhcp.dns_server[1], ethspi.dhcp.dns_server[2], ethspi.dhcp.dns_server[3]); memcpy(ip_address, ethspi.dhcp.ipaddr, 4); set_ip(ethspi.dhcp.ipaddr); client_set_gwip(ethspi.dhcp.gwip); #ifdef CONFIG_ETH_DHCP_SHOW print("eth ip address %i.%i.%i.%i\n", ethspi.dhcp.ipaddr[0], ethspi.dhcp.ipaddr[1], ethspi.dhcp.ipaddr[2], ethspi.dhcp.ipaddr[3]); #endif } return; } // 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(ethspi.rxbuf, plen)) { make_arp_answer_from_request(ethspi.rxbuf); return; } // check if ip frames (icmp or udp) are for us or broadcast: if (eth_type_is_ip_and_broadcast(ethspi.rxbuf, plen) == 0) { if (eth_type_is_ip_and_my_ip(ethspi.rxbuf, plen) == 0) { return; } if (ethspi.rxbuf[IP_PROTO_P]==IP_PROTO_ICMP_V && ethspi.rxbuf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){ // a ping frame, let's send pong make_echo_reply_from_request(ethspi.rxbuf, plen); return; } } #if 0 // we listen on port 0xcafe if (ethspi.rxbuf[IP_PROTO_P] == IP_PROTO_UDP_V && ethspi.rxbuf[UDP_DST_PORT_H_P] == 0xca && ethspi.rxbuf[UDP_DST_PORT_L_P] == 0xf) { int payloadlen = ethspi.rxbuf[UDP_LEN_L_P];//plen - 34 - UDP_HEADER_LEN; DBG(D_ETH, D_DEBUG, "ethspi UDP len:%i\n", payloadlen); //char *nisse = "hello wurlde"; //make_udp_reply_from_request(ethbuf, nisse, strlen(nisse), 1200); DBG(D_ETH, D_DEBUG, "ethspi eth mac dst: %02x.%02x.%02x.%02x.%02x.%02x\n", ethspi.rxbuf[0], ethspi.rxbuf[1], ethspi.rxbuf[2], ethspi.rxbuf[3], ethspi.rxbuf[4], ethspi.rxbuf[5]); // ETH_DST_MAC DBG(D_ETH, D_DEBUG, "ethspi eth mac src: %02x.%02x.%02x.%02x.%02x.%02x\n", ethspi.rxbuf[6], ethspi.rxbuf[7], ethspi.rxbuf[8], ethspi.rxbuf[9], ethspi.rxbuf[10], ethspi.rxbuf[11]); // ETH_SRC_MAC DBG(D_ETH, D_DEBUG, "ethspi eth type: %02x %02x\n", ethspi.rxbuf[12], ethspi.rxbuf[13]); // ETH_TYPE_H_P, ETH_TYPE_L_P DBG(D_ETH, D_DEBUG, "ethspi ip src: %i.%i.%i.%i\n", ethspi.rxbuf[26], ethspi.rxbuf[27], ethspi.rxbuf[28], ethspi.rxbuf[29]); // IP_SRC_P DBG(D_ETH, D_DEBUG, "ethspi ip dst: %i.%i.%i.%i\n", ethspi.rxbuf[30], ethspi.rxbuf[31], ethspi.rxbuf[32], ethspi.rxbuf[33]); // IP_DST_P DBG(D_ETH, D_DEBUG, "ethspi udp src port: %i\n", (ethspi.rxbuf[34] << 8) | ethspi.rxbuf[35]); // UDP_SRC_PORT_H_P DBG(D_ETH, D_DEBUG, "ethspi udp dst port: %i\n", (ethspi.rxbuf[36] << 8) | ethspi.rxbuf[37]); // UDP_DST_PORT_H_P DBG(D_ETH, D_DEBUG, "ethspi udp len: %04x\n", (ethspi.rxbuf[38] << 8) | ethspi.rxbuf[39]); // UDP_LEN_H_P DBG(D_ETH, D_DEBUG, "ethspi udp checksum: %04x\n", (ethspi.rxbuf[40] << 8) | ethspi.rxbuf[41]); // UDP_CHECKSUM_H_P } IF_DBG(D_ETH, D_DEBUG) { printbuf(ðspi.rxbuf[0], plen); }