/*---------------------------------------------------------------------------*/ int main(void) { uint16_t plen; init_serial(); init_mac(mymac); init_udp_or_www_server(mymac,myip); enc28j60Init(mymac); enc28j60PhyWrite(PHLCON,0x476); enc28j60EnableBroadcast(); xprintf(PSTR("Hello World!\r\n")); /* main loop */ while(1) { /* poll hardware ethernet buffer */ plen = enc28j60PacketReceive(BUFFER_SIZE,buf); /* any new message? */ if(plen > 0) { checkBootloaderCondition(buf); } } return 0; }
static struct pbuf *low_level_input( struct netif *netif ) { struct pbuf *q,*p = NULL; u16 Len = 0; int i =0; Len = enc28j60PacketReceive(1520 *4, Data_Buf); //返回接收到的数据包长度 if ( Len == 0 ) return 0; p = pbuf_alloc(PBUF_RAW, Len, PBUF_POOL); if (p != NULL) { for (q = p; q != NULL; q = q->next) { memcpy((u8_t*)q->payload, (u8_t*)&Data_Buf[i], q->len); i = i + q->len; } if( i != p->tot_len ){ return 0;} //相等时表明到了数据尾 } return p; }
/** * Should allocate a pbuf and transfer the bytes of the incoming * packet from the interface into the pbuf. * * @param netif the lwip network interface structure for this ethernetif * @return a pbuf filled with the received packet (including MAC header) * NULL on memory error */ static struct pbuf * low_level_input(struct netif *netif) { struct pbuf *p, *q; u16_t len; //uint32_t l=0,i =0; //FrameTypeDef frame; //u8_t *buffer; p = NULL; /* Obtain the size of the packet and put it into the "len" variable. */ len = enc28j60BeginPacketReceive(); if(!len) { #ifdef DEBUG debug_printf("ETH DEBUG: low_level_input %d\n\r", len); #endif return NULL; } #if ETH_PAD_SIZE len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ #endif /* We allocate a pbuf chain of pbufs from the pool. */ p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); if (p != NULL) { #if ETH_PAD_SIZE pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ #endif /* We iterate over the pbuf chain until we have read the entire * packet into the pbuf. */ for(q = p; q != NULL; q = q->next) { /* Read enough bytes to fill this pbuf in the chain. The * available data in the pbuf is given by the q->len * variable. */ //read data into(q->payload, q->len); enc28j60PacketReceive(q->payload, q->len); } //acknowledge that packet has been read(); enc28j60EndPacketReceive(); #if ETH_PAD_SIZE pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ #endif // LINK_STATS_INC(link.recv); } else { //drop packet(); enc28j60EndPacketReceive(); //LINK_STATS_INC(link.memerr); //LINK_STATS_INC(link.drop); } return p; }
struct pbuf *PacketReceive(struct netif *netif) { struct pbuf *p = NULL; unsigned int recvlen = 0; unsigned int i = 0; struct pbuf *q = NULL; recvlen = enc28j60PacketReceive(1500, MyRecvbuf); if(!recvlen) //接收数据长度为0,直接返回空 { return NULL; } //申请内核pbuf空间,为RAM类型 p = pbuf_alloc(PBUF_RAW, recvlen, PBUF_RAM); if(!p) //申请失败,则返回空 { LWIP_PLATFORM_DIAG(("PacketReceive: pbuf_alloc fail ,len=%"U32_F"\n\t", recvlen)); return NULL; } //申请成功,拷贝数据到pbuf中 q = p; while(q != NULL) { memcpy(q->payload,&MyRecvbuf[i],q->len); i += q->len; q = q->next; if(i >= recvlen) break; } return p; }
uint16_t nic_poll(void) { uint16_t packetLength; packetLength = enc28j60BeginPacketReceive(); // if there's no packet or an error - exit without ending the operation if( !packetLength ) return 0; // drop anything too big for the buffer if( packetLength > UIP_BUFSIZE ) { #ifdef DEBUG_SERIAL printf("Recieved big packet %i bytes, dropping \r\n",(int)uip_len); #endif enc28j60EndPacketReceive(); return 0; } // copy the packet data into the uIP packet buffer enc28j60PacketReceive( uip_buf, packetLength ); enc28j60EndPacketReceive(); #ifdef DEBUG_SERIAL printf("Recieved & transferred to uip, packet %i bytes\r\n",(int)uip_len); #endif return packetLength; }
int main(void){ uint16_t dat_p; // set the clock speed to 8MHz // set the clock prescaler. First write CLKPCE to enable setting of clock the // next four instructions. CLKPR=(1<<CLKPCE); CLKPR=0; // 8 MHZ _delay_loop_1(0); // 60us //initialize the hardware driver for the enc28j60 enc28j60Init(mymac); //enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz _delay_loop_1(0); // 60us enc28j60PhyWrite(PHLCON,0x476); PORTB = 0xff; DDRB = 0xff; uart_init(); sei(); xfunc_out = (void (*)(char))uart_put; xputs(PSTR("AVR-Ethernet test monitor\n")); xprintf(PSTR("ENC28J60 Rev.%d\n"), enc28j60getrev()); //init the ethernet/ip layer: init_ip_arp_udp_tcp(mymac,myip,MYWWWPORT); while(1){ // read packet, handle ping and wait for a tcp packet: dat_p=packetloop_icmp_tcp(buf,enc28j60PacketReceive(BUFFER_SIZE, buf)); /* dat_p will be unequal to zero if there is a valid * http get */ if(dat_p==0){ // no http request continue; } // tcp port 80 begin if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){ // head, post and other methods: dat_p=http200ok(); dat_p=fill_tcp_data_p(buf,dat_p,PSTR("<h1>200 OK</h1>")); goto SENDTCP; } // just one web page in the "root directory" of the web server if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0){ dat_p=print_webpage(buf); goto SENDTCP; }else{ 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; } SENDTCP: www_server_reply(buf,dat_p); // send web page data // tcp port 80 end } return (0); }
void NanodeUIP::poll(void) { int i; uip_len = enc28j60PacketReceive(UIP_BUFSIZE,uip_buf); if(uip_len > 0) { if(BUF->type == UIP_HTONS(UIP_ETHTYPE_IP)) { uip_arp_ipin(); uip_input(); /* If the above function invocation resulted in data that should be sent out on the network, the global variable uip_len is set to a value > 0. */ if(uip_len > 0) { uip_arp_out(); enc28j60PacketSend(uip_len,uip_buf); } } else if(BUF->type == UIP_HTONS(UIP_ETHTYPE_ARP)) { uip_arp_arpin(); /* If the above function invocation resulted in data that should be sent out on the network, the global variable uip_len is set to a value > 0. */ if(uip_len > 0) { enc28j60PacketSend(uip_len,uip_buf); } } } else if(timer_expired(&periodic_timer)) { timer_reset(&periodic_timer); for(i = 0; i < UIP_CONNS; i++) { uip_periodic(i); /* If the above function invocation resulted in data that should be sent out on the network, the global variable uip_len is set to a value > 0. */ if(uip_len > 0) { uip_arp_out(); enc28j60PacketSend(uip_len,uip_buf); } } #if UIP_UDP for(i = 0; i < UIP_UDP_CONNS; i++) { uip_udp_periodic(i); /* If the above function invocation resulted in data that should be sent out on the network, the global variable uip_len is set to a value > 0. */ if(uip_len > 0) { uip_arp_out(); enc28j60PacketSend(uip_len,uip_buf); } } #endif /* UIP_UDP */ /* Call the ARP timer function every 10 seconds. */ if(timer_expired(&arp_timer)) { timer_reset(&arp_timer); uip_arp_timer(); } } }
// 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; }
static struct pbuf * low_level_2_input(struct netif *netif) { struct pbuf *p; SYS_ARCH_DECL_PROTECT(sr); SYS_ARCH_PROTECT(sr); p = enc28j60PacketReceive(); SYS_ARCH_UNPROTECT(sr); return p; }
// 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; }
/** * Should allocate a pbuf and transfer the bytes of the incoming * packet from the interface into the pbuf. * * @param netif the lwip network interface structure for this ethernetif * @return a pbuf filled with the received packet (including MAC header) * NULL on memory error */ static struct pbuf * low_level_input(struct netif *netif) { struct ethernetif *ethernetif = netif->state; struct pbuf *q,*p = NULL; u16 Len = 0; int i =0; /* Obtain the size of the packet and put it into the "len" variable. */ Len = enc28j60PacketReceive(1520 *4, Data_Buf); //返回接收到的数据包长度 #if ETH_PAD_SIZE len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ #endif if ( Len == 0 ) return 0; /* We allocate a pbuf chain of pbufs from the pool. */ p = pbuf_alloc(PBUF_RAW, Len, PBUF_POOL); if (p != NULL) { #if ETH_PAD_SIZE pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ #endif /* We iterate over the pbuf chain until we have read the entire * packet into the pbuf. */ for(q = p; q != NULL; q = q->next) { memcpy((u8_t*)q->payload, (u8_t*)&Data_Buf[i], q->len); i = i + q->len; } if( i != p->tot_len ){ return 0;} //相等时表明到了数据尾 } return p; #if ETH_PAD_SIZE pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ #endif }
u8_t nic_poll(void) { u16_t packetLength; packetLength = enc28j60PacketReceive(UIP_BUFSIZE, (uint8_t*)uip_buf); // If there are no incoming data if(!packetLength) return packetLength = 0; // If the length exceed the buffer size if(packetLength > UIP_BUFSIZE) return packetLength = 0; // Return the length return packetLength; }
static uint16_t network_read(void) { uint16_t len; #if CONFIG_DRIVERS_ENC28J60 len = enc28j60PacketReceive(UIP_BUFSIZE, (uint8_t *)uip_buf); #endif #if CONFIG_DRIVERS_ENC424J600 len = enc424j600PacketReceive(UIP_BUFSIZE, (uint8_t *)uip_buf); #endif #if TCPDUMP if (len > 0) { printf_P(PSTR("IN: ")); tcpdump(uip_buf, len); } #endif return len; }
//Documentation in header file uint8_t dhcp_requestIP(uint16_t timeout_ms) { //Get a timer int8_t timer = timer_get(); timer_set(timer,timeout_ms); //Send dhcp discover packet dhcp_sendDiscover(); do { //Wait for a packet to arrive //If no packets arrive in time, return 0 while(enc28j60Read(EPKTCNT) == 0) if(timer_check(timer) == TIMER_EXPIRED) { //Release the timer timer_release(timer); return 0; } //Receive packet ns.plength = enc28j60PacketReceive(ns.pbuf, ns.pbuf_size); //Check if packet is DHCP! if(ns.plength > 0) if(getPacketType() == DHCP) dhcp_handlePacket(); } while(ns.ipAcquired == 0); //Release the timer timer_release(timer); //Return success return ns.ipAcquired; }
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); }
unsigned int network_read(void){ return ((uint16_t) enc28j60PacketReceive(UIP_BUFSIZE, (uint8_t *)uip_buf)); }
//Read a packet from the controller and place it in the uIP buffer. //The length of the packet is returned, 0 if no packet was waiting. unsigned int network_read(void){ uint16_t len; len=enc28j60PacketReceive(UIP_BUFSIZE, (uint8_t *)uip_buf); return len; }
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); }
int main(void) { uint16_t dat_p; ADC_init(); _delay_ms ( 100 ); //DDRB |= (1<<PB0); initTimer(); //initialize the hardware driver for the enc28j60 enc28j60Init(mymac); enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz _delay_loop_1(0); // 60us enc28j60PhyWrite(PHLCON,0x476); //init the ethernet/ip layer: init_udp_or_www_server(mymac,myip); www_server_port(MYWWWPORT); while(1) { // read packet, handle ping and wait for a tcp packet: dat_p=packetloop_arp_icmp_tcp(buf,enc28j60PacketReceive(BUFFER_SIZE, buf)); // dat_p will be unequal to zero if there is a valid http get if(dat_p==0) { // no http request continue; } // tcp port 80 begin if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0) { // head, post and other methods: dat_p=http200ok(); dat_p=fill_tcp_data_p(buf,dat_p,PSTR("<h1>200 OK</h1>")); www_server_reply(buf,dat_p); continue; } // just one web page in the "root directory" of the web server if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0) { //dat_p=print_webpage(buf); dat_p=printIndex(buf); www_server_reply(buf,dat_p); } else if (strncmp("/now.htm", (char *)&(buf[dat_p+4]),8) == 0 ) { dat_p = printNowHTML ( buf ); www_server_reply( buf, dat_p ); } else if (strncmp("/min0.htm", (char *)&(buf[dat_p+4]),9) == 0 ) { dat_p = printMinHTML ( buf, 0 ); www_server_reply( buf, dat_p ); } else if (strncmp("/min1.htm", (char *)&(buf[dat_p+4]),9) == 0 ) { dat_p = printMinHTML ( buf, 1 ); www_server_reply( buf, dat_p ); } else if (strncmp("/wlcm.htm", (char *)&(buf[dat_p+4]),9) == 0 ) { dat_p = printWelcomeHTML ( buf ); www_server_reply( buf, dat_p ); } else { 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>")); www_server_reply(buf,dat_p); } } return (0); }
uint16_t etherdev_read(uint8_t *p_char) { return enc28j60PacketReceive(1500,p_char); }
int simple_server(void) { unsigned int plen; unsigned int dat_p; unsigned char i=0; unsigned char cmd_pos=0; unsigned char cmd; unsigned char payloadlen=0; char str[30]; char cmdval; // Del_1ms(100); /*initialize enc28j60*/ enc28j60Init(mymac); init_ip_arp_udp_tcp(mymac,myip,mywwwport); //ָʾµÆ״̬:0x476 is PHLCON LEDA(ÂÌ)=links status, LEDB(ºì)=receive/transmit enc28j60PhyWrite(PHLCON,0x7a4); enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz // Del_1ms(20); //init the ethernet/ip layer: while(1) { // OSTimeDlyHMSM(0, 0, 0, 50); // get the next new packet: plen = enc28j60PacketReceive(BUFFER_SIZE, buf); //USART_DMASendData(USART1,buf,plen); /*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. if(eth_type_is_arp_and_my_ip(buf,plen)) { make_arp_answer_from_request(buf); //USART_DMASendText(USART1,"make_arp_answer_from_request\n"); 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 make_echo_reply_from_request(buf, plen); //USART_DMASendText(USART1,"make_echo_reply_from_request\n"); 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; } 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<h1>200 OK</h1>")); 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("<p>Usage: ")); plen=fill_tcp_data(buf,plen,baseurl); plen=fill_tcp_data_p(buf,plen,PSTR("password</p>")); goto SENDTCP; } cmd=analyse_get_url((char *)&(buf[dat_p+5])); // for possible status codes see: // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html 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<h1>401 Unauthorized</h1>")); goto SENDTCP; } if (cmd==1) { //PORTD|= (1<<PD7);// transistor on //IOCLR |= (1<<26); // LED1ON(); i=1; } if (cmd==0) { //PORTD &= ~(1<<PD7);// transistor off //IOSET |= (1<<26); // LED1OFF(); i=0; } // if (cmd==-2) or any other value // just display the status: plen=print_webpage(buf,(i)); 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') { //PORTD|= (1<<PD7);// transistor on //IOCLR |= (1<<26); //LED1ON(); strcpy(str,"t=1"); goto ANSWER; } else if(cmdval=='0') { //PORTD &= ~(1<<PD7);// transistor off //IOSET |= (1<<26); //LED1OFF(); strcpy(str,"t=0"); goto ANSWER; } else if(cmdval=='?') { /* if (IOPIN & (1<<26)) { 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); } } // return (0); }
/** * Handle Modbus requests * Checks for new TCP data and looks for new modbus messages **/ void mb_handleRequest(void) { // read packet, handle ping and wait for a tcp packet uint16_t dat_p = packetloop_icmp_tcp(buf,enc28j60PacketReceive(BUFFER_SIZE, buf)); // check if data was received if (dat_p == 0) return; // make structure pointer to buffer modbusmsg_t* msg = (modbusmsg_t*)&buf[dat_p]; // check for modbus protocol id if (FROM_UINT16(msg->mbap.protoId) > 0) return; uint16_t len; switch (msg->function) { // Modbus read function case MB_FUNC_READREG: { readreg_req_t* req = (readreg_req_t*)&(msg->function); readreg_res_t* res = (readreg_res_t*)&(msg->function); uint16_t amount = FROM_UINT16(req->amount); uint16_t addr = FROM_UINT16(req->start_address); if (amount == 0 || amount > 0x7D) { len = mb_set_error(msg,MB_ERR_DATA); break; } if (addr + amount <= MODBUS_REGISTER_COUNT) { uint16_t *ptr = (uint16_t*)&(res->function); uint16_t cnt = 0; for (; cnt < amount; cnt++) { if (registers[addr+cnt] == NULL) { len = mb_set_error(msg,MB_ERR_PROC); break; } ++ptr; *ptr = TO_UINT16(*(registers[addr+cnt])); } // if an error occurred if (cnt < amount) break; res->bytecount = cnt*sizeof(uint16_t); len = sizeof(readreg_res_t)+cnt*sizeof(uint16_t); } else len = mb_set_error(msg,MB_ERR_ADDR); break; } // Modbus write function case MB_FUNC_WRITEREG: { writereg_req_t* req = (writereg_req_t*)&(msg->function); uint16_t addr = FROM_UINT16(req->start_address); uint16_t value = FROM_UINT16(req->value); if (addr >= MODBUS_REGISTER_COUNT || writecbs[addr] == NULL) { len = mb_set_error(msg,MB_ERR_ADDR); break; } if (writecbs[addr](addr,value)) len = sizeof(writereg_req_t); else len = mb_set_error(msg,MB_ERR_PROC); break; } // Modbus device id function // Not implemented completely case MB_FUNC_DEV_ID: { devid_req_t* req = (devid_req_t*)&(msg->function); devid_res_t* res = (devid_res_t*)&(msg->function); devid_obj_t* obj = (devid_obj_t*)&(res->nextobjid); uint8_t i = req->objid; if (req->type != 0x0E) { len = mb_set_error(msg,MB_ERR_FUNC); break; } if (!req->code || req->code > 4) { len = mb_set_error(msg,MB_ERR_DATA); break; } res->conflevel = 0x01; res->more = 0x00; res->nextobjid = 0x00; res->amount = 3; len = sizeof(devid_res_t); if (i > 2) i = 0; // add requested objects for (; i < 3; i++) { ++obj; obj->id = i; obj->length = 0; len += sizeof(devid_obj_t)+obj->length; } break; } default: // set error len = mb_set_error(msg,MB_ERR_FUNC); break; } msg->mbap.length = TO_UINT16(len+1); // send response www_server_reply(buf,sizeof(mbap_t)+len); }
int main(void){ uint16_t plen; uint8_t i=0; uint8_t cmd_pos=0; uint8_t payloadlen=0; char str[30]; char cmdval; // set the clock speed to 8MHz // set the clock prescaler. First write CLKPCE to enable setting of clock the // next four instructions. CLKPR=(1<<CLKPCE); CLKPR=0; // 8 MHZ delay_ms(10); /* enable PB0, reset as output */ DDRB|= (1<<DDB0); /* enable PD2/INT0, as input */ DDRD&= ~(1<<DDD2); /* set output to gnd, reset the ethernet chip */ PORTB &= ~(1<<PB0); delay_ms(10); /* set output to Vcc, reset inactive */ PORTB|= (1<<PB0); delay_ms(200); /*initialize enc28j60*/ enc28j60Init(mymac); delay_ms(20); // LED /* enable PB1, LED as output */ DDRB|= (1<<DDB1); /* set output to Vcc, LED off */ PORTB|= (1<<PB1); // the transistor on PD7 DDRD|= (1<<DDD7); PORTD &= ~(1<<PD7);// transistor off /* 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); delay_ms(20); /* set output to GND, red LED on */ PORTB &= ~(1<<PB1); i=1; //init the ethernet/ip layer: init_ip_arp_udp(mymac,myip); while(1){ // get the next new packet: plen = enc28j60PacketReceive(BUFFER_SIZE, buf); /*plen will ne unequal to zero if there is a valid * packet (without crc error) */ if(plen==0){ continue; } // led---------- if (i){ /* set output to Vcc, LED off */ PORTB|= (1<<PB1); i=0; }else{ /* set output to GND, LED on */ PORTB &= ~(1<<PB1); i=1; } // 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)){ make_arp_answer_from_request(buf,plen); continue; } // check if ip packets (icmp or udp) 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 make_echo_reply_from_request(buf,plen); continue; } // we listen on 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'){ PORTD|= (1<<PD7);// transistor on strcpy(str,"t=1"); goto ANSWER; }else if(cmdval=='0'){ PORTD &= ~(1<<PD7);// transistor off strcpy(str,"t=0"); goto ANSWER; }else if(cmdval=='?'){ if (PORTD & (1<<PD7)){ 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),myport); } } return (0); }
int main(void){ uint16_t plen; uint16_t dat_p; uint8_t i=0; uint8_t payloadlen=0; // set the clock speed to 8MHz // set the clock prescaler. First write CLKPCE to enable setting of clock the // next four instructions. //CLKPR=(1<<CLKPCE); //CLKPR=0; // 8 MHZ _delay_loop_1(50); // 12ms // LED /* enable PB1, LED as output */ DDRB|= (1<<DDB1); /* one blink for indicate of start programm */ cbi(PORTB, PORTB1); // on _delay_ms(100); sbi(PORTB,PORTB1); // off _delay_ms(100); cbi(PORTB,PORTB1); // on /*initialize enc28j60*/ enc28j60Init(mymac); enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz _delay_loop_1(50); // 12ms /* 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); _delay_loop_1(50); // 12ms /* set output to GND, red LED on */ PORTB &= ~(1<<PORTB1); i=1; //init the ethernet/ip layer: init_ip_arp_udp_tcp(mymac,myip,MYWWWPORT); while(1){ // get the next new packet: 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. if(eth_type_is_arp_and_my_ip(buf,plen)){ make_arp_answer_from_request(buf); continue; } // check if ip packets (icmp or udp) are for us: if(eth_type_is_ip_and_my_ip(buf,plen)==0){ continue; } if (i){ /* set output to Vcc, LED off */ PORTB|= (1<<PORTB1); i=0; }else{ /* set output to GND, LED on */ PORTB &= ~(1<<PORTB1); i=1; } if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V){ // a ping packet, let's send pong 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; } 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<h1>200 OK</h1>")); }else{ // the "get" method plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<p>OK, it works</p>")); } make_tcp_ack_from_any(buf); // send ack for http get make_tcp_ack_with_data(buf,plen); // send data continue; } } // udp interface: if (buf[IP_PROTO_P]==IP_PROTO_UDP_V){ payloadlen=buf[UDP_LEN_L_P]-UDP_HEADER_LEN; // the received command has to start with t and be 4 char long // e.g "test\0" if (buf[UDP_DATA_P]=='t' && payloadlen==5){ make_udp_reply_from_request(buf,"hello",6,MYUDPPORT); } } } return (0); }
int simple_servercycle(void) { uchar tIPAddr[4]; char i,nS,freeSlot; unsigned int j; // OSTimeDlyHMSM(0, 0, 0, 50); // get the next new packet: plen = enc28j60PacketReceive(BUFFER_SIZE, fbuf); //USART_DMASendData(USART1,fbuf,plen); /*plen will ne unequal to zero if there is a valid packet (without crc error) */ if(plen==0) { 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(fbuf,plen)) { make_arp_answer_from_request(fbuf); //USART_DMASendText(USART1,"make_arp_answer_from_request\n"); return; } // check if ip packets are for us: if(eth_type_is_ip_and_my_ip(fbuf,plen)==0) { return; } if(fbuf[IP_PROTO_P]==IP_PROTO_ICMP_V && fbuf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V) { // a ping packet, let's send pong make_echo_reply_from_request(fbuf, plen); //USART_DMASendText(USART1,"make_echo_reply_from_request\n"); return; } // tcp port www start, compare only the lower byte if (fbuf[IP_PROTO_P]==IP_PROTO_TCP_V&&fbuf[TCP_DST_PORT_H_P]==(*PORTNUMBER)/256&&fbuf[TCP_DST_PORT_L_P]==(*PORTNUMBER)%256) { nS=101; freeSlot=9; for (i=0;i<MAX_SOCKET_COUNT;i++) { Sockets[i].Timeout--; if (Sockets[i].Timeout<0) { Sockets[i].Timeout=0; Sockets[i].IP_PHASE=0; } if (!Sockets[i].IP_PHASE) freeSlot=i; BufCpy(tIPAddr,Sockets[i].IP_source,4); if (check_ip_scr(fbuf,tIPAddr)) { nS=i;break; } } if (nS>100) nS=freeSlot; //nS=0; if (fbuf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V) { make_tcp_synack_from_syn(fbuf); // make_tcp_synack_from_syn does already send the syn,ack Sockets[nS].IP_PHASE=ETH_HEAD; Sockets[nS].Timeout=20; BufCpy(Sockets[nS].IP_source,tIPAddr,4); return; } if (fbuf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V) { GlobData++; init_len_info(fbuf); // init some data structures // we can possibly have no data, just ack: dat_p=get_tcp_data_pointer(); if (dat_p==0) { if (fbuf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V) { // finack, answer with ack make_tcp_ack_from_any(fbuf); return; } // just an ack with no data, wait for next packet } else { j=checksum(&fbuf[IP_SRC_P], 8+TCP_HEADER_LEN_PLAIN+info_data_len,2); if (j) return; } check_ip_scr(fbuf,tIPAddr); // GlobData++; BufCpy(Sockets[nS].IP_source,tIPAddr,4); SocketUpdate(nS,fbuf,dat_p,&plen); if (plen) make_tcp_ack_with_data(fbuf,plen,0); // send data else make_tcp_ack_from_any(fbuf); // send ack for http get return; } } // tcp port www end // }
/* * Main entry point */ int main(void) { //=====init green led LEDInit(); LEDSet(1); //=====setup eth interface uint16_t plen = 0, dat_p = 0; //initialize enc28j60 enc28j60Init(mymac); _delay_ms(100); // 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); _delay_ms(100); //init the ethernet/ip layer: init_udp_or_www_server(mymac,myip); www_server_port(MYWWWPORT); register_ping_rec_callback(PingCallback); while(1){ // handle ping and wait for a tcp packet: dat_p = packetloop_arp_icmp_tcp(buf, enc28j60PacketReceive(BUFFER_SIZE, buf)); // dat_p will be unequal to zero if there is a valid http get if(dat_p==0){ // do nothing continue; } // tcp port 80 begin if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){ dat_p = 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")); dat_p = fill_tcp_data_p(buf, dat_p, PSTR("<h1>200 OK</h1>")); goto SENDTCP; } if (strncmp("/ ",(char *) & (buf[ dat_p + 4] ), 2) == 0 ){ nAccessCount++; dat_p = 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")); // webcontent char szWebText[130] = {0}; sprintf(szWebText, "<b>ATmega8 Webserver / ENC28J60</b><br><br>Server stats:<br>Acc:%d Png:%d<br><br>(C) Radu Motisan 2012, www.pocketmagic.net<br/>Tomasz Jokiel", nAccessCount, nPingCount); dat_p = fill_tcp_data(buf, dat_p, szWebText); // goto SENDTCP; } // all other URLs: 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>")); SENDTCP: www_server_reply(buf, dat_p); // send web page data } return (0); }
uint16_t network_read(uint16_t size, uint8_t * buffer) { return enc28j60PacketReceive(size, buffer); }
uint16_t EtherShield::ES_enc28j60PacketReceive(uint16_t len, uint8_t* packet){ return enc28j60PacketReceive(len, packet); }
uint32_t net_recv() { net_nrecv = enc28j60PacketReceive(1500, &net_buffer); return net_nrecv; }