See http://mbed.org/users/no2chem/notebook/ethernet-testing/ For usage information.

Dependencies:   mbed lwip

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "lwip/opt.h"
00003 #include "lwip/stats.h"
00004 #include "lwip/sys.h"
00005 #include "lwip/pbuf.h"
00006 #include "lwip/udp.h"
00007 #include "lwip/tcp.h"
00008 #include "lwip/dns.h"
00009 #include "lwip/dhcp.h"
00010 #include "lwip/init.h"
00011 #include "lwip/netif.h"
00012 #include "netif/etharp.h"
00013 #include "netif/loopif.h"
00014 #include "device.h"
00015 
00016 Ethernet ethernet;
00017 DigitalOut ledLink(p30);
00018 DigitalOut ledActivity(p29);
00019 DigitalOut ledStage0 (LED1);
00020 DigitalOut ledStage1 (LED2);
00021 DigitalOut ledStage2 (LED3);
00022 DigitalOut ledTCP80 (LED4);
00023 
00024 volatile char stage = 0;
00025 
00026 Ticker stage_blinker;
00027 
00028 struct netif    netif_data;
00029 
00030 const char testPage[] = "HTTP/1.1 200 OK\r\n"
00031                         "Content-Type: text/html\r\n"
00032                         "Connection: Close\r\n\r\n"
00033                         "<html>"
00034                         "<head>"
00035                         "<title>mbed test page</title>"
00036                         "<style type='text/css'>"
00037                         "body{font-family:'Arial, sans-serif', sans-serif;font-size:.8em;background-color:#fff;}"
00038                         "</style>"
00039                         "</head>"
00040                         "<body>%s</body></html>\r\n\r\n";
00041 
00042 char buffer[1024];
00043 char temp[1024];
00044 err_t recv_callback(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) {
00045     struct netif   *netif = &netif_data;
00046     ledTCP80 = true;
00047     printf("TCP callback from %d.%d.%d.%d\r\n", ip4_addr1(&(pcb->remote_ip)),ip4_addr2(&(pcb->remote_ip)),ip4_addr3(&(pcb->remote_ip)),ip4_addr4(&(pcb->remote_ip)));
00048     char *data;
00049     /* Check if status is ok and data is arrived. */
00050     if (err == ERR_OK && p != NULL) {
00051         /* Inform TCP that we have taken the data. */
00052         tcp_recved(pcb, p->tot_len);
00053         data = static_cast<char *>(p->payload);
00054         /* If the data is a GET request we can handle it. */
00055         if (strncmp(data, "GET ", 4) == 0) {
00056         printf("Handling GET request...\r\n");
00057         printf("Request:\r\n%s\r\n", data);
00058         
00059         //generate the test page
00060         time_t seconds = time(NULL);
00061         sprintf(temp,     "<h1>Congratulations!</h1>If you can see this page, your mbed is working properly."
00062                           "<h2>mbed Configuration</h2>"
00063                           "mbed RTC time:%s<br/>"
00064                           "mbed HW address: %02x:%02x:%02x:%02x:%02x:%02x<br/>"
00065                           "mbed IP Address: %s<br/>",
00066          ctime(&seconds),
00067         (char*) netif->hwaddr[0],
00068         (char*) netif->hwaddr[1],
00069         (char*) netif->hwaddr[2],
00070         (char*) netif->hwaddr[3],
00071         (char*) netif->hwaddr[4],
00072         (char*) netif->hwaddr[5],
00073         inet_ntoa(*(struct in_addr*)&(netif->ip_addr))
00074         );
00075         sprintf(buffer, testPage, temp);
00076             if (tcp_write(pcb, (void *)buffer, strlen(buffer), 1) == ERR_OK) {
00077             tcp_output(pcb);
00078             printf("Closing connection...\r\n");
00079             tcp_close(pcb);
00080             }
00081         }
00082         else
00083         {
00084             printf("Non GET request...\r\nRequest:\r\n%s\r\n", data);
00085         }
00086         
00087         pbuf_free(p);
00088     }
00089     
00090      else {
00091             /* No data arrived */
00092             /* That means the client closes the connection and sent us a packet with FIN flag set to 1. */
00093             /* We have to cleanup and destroy out TCPConnection. */
00094              printf("Connection closed by client.\r\n");
00095             pbuf_free(p);
00096         }
00097     /* Don't panic! Everything is fine. */
00098     ledTCP80 = false;
00099     return ERR_OK;
00100 }
00101 /* Accept an incomming call on the registered port */
00102 err_t accept_callback(void *arg, struct tcp_pcb *npcb, err_t err) {
00103     LWIP_UNUSED_ARG(arg);
00104     /* Subscribe a receive callback function */
00105     tcp_recv(npcb, &recv_callback);
00106     /* Don't panic! Everything is fine. */
00107     return ERR_OK;
00108 }
00109 
00110 void stageblinker()
00111 {
00112     switch (stage)
00113     {
00114         case 0:
00115         ledStage0 = !ledStage0;
00116         ledStage1 = false;
00117         ledStage2 = false;
00118         break;
00119         case 1:
00120         ledStage0 = true;
00121         ledStage1 = !ledStage1;
00122         ledStage2 = false;
00123         break;
00124         case 2:
00125         ledStage0 = true;
00126         ledStage1 = true;
00127         ledStage2 = true;
00128         stage_blinker.detach();
00129         break;
00130     }
00131 }
00132 
00133 int main() {
00134     printf("mBed Ethernet Tester 1.0\r\nStarting Up...\r\n");
00135     stage = 0;
00136     struct netif   *netif = &netif_data;
00137     struct ip_addr  ipaddr;
00138     struct ip_addr  netmask;
00139     struct ip_addr  gateway;
00140     Ticker tickFast, tickSlow, tickARP, eth_tick, dns_tick, dhcp_coarse, dhcp_fine;
00141     stage_blinker.attach_us(&stageblinker, 1000*500);
00142     
00143     char *hostname = "my-mbed";
00144     
00145     printf("Configuring device for DHCP...\r\n");
00146     /* Start Network with DHCP */
00147     IP4_ADDR(&netmask, 255,255,255,255);
00148     IP4_ADDR(&gateway, 0,0,0,0);
00149     IP4_ADDR(&ipaddr, 0,0,0,0);
00150     /* Initialise after configuration */
00151     lwip_init();
00152     netif->hwaddr_len = ETHARP_HWADDR_LEN;
00153     device_address((char *)netif->hwaddr);
00154     netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, device_init, ip_input);
00155     netif->hostname = hostname;
00156     netif_set_default(netif);
00157     dhcp_start(netif); // <-- Use DHCP
00158     
00159         /* Initialise all needed timers */
00160     tickARP.attach_us( &etharp_tmr,  ARP_TMR_INTERVAL  * 1000);
00161     tickFast.attach_us(&tcp_fasttmr, TCP_FAST_INTERVAL * 1000);
00162     tickSlow.attach_us(&tcp_slowtmr, TCP_SLOW_INTERVAL * 1000);
00163     dns_tick.attach_us(&dns_tmr, DNS_TMR_INTERVAL * 1000);
00164     dhcp_coarse.attach_us(&dhcp_coarse_tmr, DHCP_COARSE_TIMER_MSECS * 1000);
00165     dhcp_fine.attach_us(&dhcp_fine_tmr, DHCP_FINE_TIMER_MSECS * 1000);
00166     stage = 1;
00167          while (!netif_is_up(netif)) { 
00168          ledLink = ethernet.link();
00169          device_poll(); 
00170      } 
00171 
00172 /*
00173     while (!(netif->dhcp->state == DHCP_BOUND || netif->dhcp->state == DHCP_PERMANENT))
00174     {
00175         ledLink = ethernet.link();
00176         device_poll();    
00177         //printf("Waiting for DHCP response, state = %d\r\n", netif->dhcp->state);
00178         //wait_ms(100);
00179         }
00180     */
00181     stage = 2;
00182             printf("Interface is up, local IP is %s\r\n", 
00183 inet_ntoa(*(struct in_addr*)&(netif->ip_addr))); 
00184 
00185     printf("Starting Web Server...\r\n");
00186 
00187         /* Bind a function to a tcp port */
00188     struct tcp_pcb *pcb = tcp_new();
00189     if (tcp_bind(pcb, IP_ADDR_ANY, 80) == ERR_OK) {
00190         pcb = tcp_listen(pcb);
00191         tcp_accept(pcb, &accept_callback);
00192     }
00193     
00194     printf("Waiting for connection...\r\n");
00195     while(1) {
00196         device_poll();
00197         ledLink = ethernet.link();
00198     }
00199 }