Michael Wei
/
EthernetTester
See http://mbed.org/users/no2chem/notebook/ethernet-testing/ For usage information.
main.cpp@0:83f7908c81b1, 2010-01-21 (annotated)
- Committer:
- no2chem
- Date:
- Thu Jan 21 08:34:39 2010 +0000
- Revision:
- 0:83f7908c81b1
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
no2chem | 0:83f7908c81b1 | 1 | #include "mbed.h" |
no2chem | 0:83f7908c81b1 | 2 | #include "lwip/opt.h" |
no2chem | 0:83f7908c81b1 | 3 | #include "lwip/stats.h" |
no2chem | 0:83f7908c81b1 | 4 | #include "lwip/sys.h" |
no2chem | 0:83f7908c81b1 | 5 | #include "lwip/pbuf.h" |
no2chem | 0:83f7908c81b1 | 6 | #include "lwip/udp.h" |
no2chem | 0:83f7908c81b1 | 7 | #include "lwip/tcp.h" |
no2chem | 0:83f7908c81b1 | 8 | #include "lwip/dns.h" |
no2chem | 0:83f7908c81b1 | 9 | #include "lwip/dhcp.h" |
no2chem | 0:83f7908c81b1 | 10 | #include "lwip/init.h" |
no2chem | 0:83f7908c81b1 | 11 | #include "lwip/netif.h" |
no2chem | 0:83f7908c81b1 | 12 | #include "netif/etharp.h" |
no2chem | 0:83f7908c81b1 | 13 | #include "netif/loopif.h" |
no2chem | 0:83f7908c81b1 | 14 | #include "device.h" |
no2chem | 0:83f7908c81b1 | 15 | |
no2chem | 0:83f7908c81b1 | 16 | Ethernet ethernet; |
no2chem | 0:83f7908c81b1 | 17 | DigitalOut ledLink(p30); |
no2chem | 0:83f7908c81b1 | 18 | DigitalOut ledActivity(p29); |
no2chem | 0:83f7908c81b1 | 19 | DigitalOut ledStage0 (LED1); |
no2chem | 0:83f7908c81b1 | 20 | DigitalOut ledStage1 (LED2); |
no2chem | 0:83f7908c81b1 | 21 | DigitalOut ledStage2 (LED3); |
no2chem | 0:83f7908c81b1 | 22 | DigitalOut ledTCP80 (LED4); |
no2chem | 0:83f7908c81b1 | 23 | |
no2chem | 0:83f7908c81b1 | 24 | volatile char stage = 0; |
no2chem | 0:83f7908c81b1 | 25 | |
no2chem | 0:83f7908c81b1 | 26 | Ticker stage_blinker; |
no2chem | 0:83f7908c81b1 | 27 | |
no2chem | 0:83f7908c81b1 | 28 | struct netif netif_data; |
no2chem | 0:83f7908c81b1 | 29 | |
no2chem | 0:83f7908c81b1 | 30 | const char testPage[] = "HTTP/1.1 200 OK\r\n" |
no2chem | 0:83f7908c81b1 | 31 | "Content-Type: text/html\r\n" |
no2chem | 0:83f7908c81b1 | 32 | "Connection: Close\r\n\r\n" |
no2chem | 0:83f7908c81b1 | 33 | "<html>" |
no2chem | 0:83f7908c81b1 | 34 | "<head>" |
no2chem | 0:83f7908c81b1 | 35 | "<title>mbed test page</title>" |
no2chem | 0:83f7908c81b1 | 36 | "<style type='text/css'>" |
no2chem | 0:83f7908c81b1 | 37 | "body{font-family:'Arial, sans-serif', sans-serif;font-size:.8em;background-color:#fff;}" |
no2chem | 0:83f7908c81b1 | 38 | "</style>" |
no2chem | 0:83f7908c81b1 | 39 | "</head>" |
no2chem | 0:83f7908c81b1 | 40 | "<body>%s</body></html>\r\n\r\n"; |
no2chem | 0:83f7908c81b1 | 41 | |
no2chem | 0:83f7908c81b1 | 42 | char buffer[1024]; |
no2chem | 0:83f7908c81b1 | 43 | char temp[1024]; |
no2chem | 0:83f7908c81b1 | 44 | err_t recv_callback(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { |
no2chem | 0:83f7908c81b1 | 45 | struct netif *netif = &netif_data; |
no2chem | 0:83f7908c81b1 | 46 | ledTCP80 = true; |
no2chem | 0:83f7908c81b1 | 47 | 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))); |
no2chem | 0:83f7908c81b1 | 48 | char *data; |
no2chem | 0:83f7908c81b1 | 49 | /* Check if status is ok and data is arrived. */ |
no2chem | 0:83f7908c81b1 | 50 | if (err == ERR_OK && p != NULL) { |
no2chem | 0:83f7908c81b1 | 51 | /* Inform TCP that we have taken the data. */ |
no2chem | 0:83f7908c81b1 | 52 | tcp_recved(pcb, p->tot_len); |
no2chem | 0:83f7908c81b1 | 53 | data = static_cast<char *>(p->payload); |
no2chem | 0:83f7908c81b1 | 54 | /* If the data is a GET request we can handle it. */ |
no2chem | 0:83f7908c81b1 | 55 | if (strncmp(data, "GET ", 4) == 0) { |
no2chem | 0:83f7908c81b1 | 56 | printf("Handling GET request...\r\n"); |
no2chem | 0:83f7908c81b1 | 57 | printf("Request:\r\n%s\r\n", data); |
no2chem | 0:83f7908c81b1 | 58 | |
no2chem | 0:83f7908c81b1 | 59 | //generate the test page |
no2chem | 0:83f7908c81b1 | 60 | time_t seconds = time(NULL); |
no2chem | 0:83f7908c81b1 | 61 | sprintf(temp, "<h1>Congratulations!</h1>If you can see this page, your mbed is working properly." |
no2chem | 0:83f7908c81b1 | 62 | "<h2>mbed Configuration</h2>" |
no2chem | 0:83f7908c81b1 | 63 | "mbed RTC time:%s<br/>" |
no2chem | 0:83f7908c81b1 | 64 | "mbed HW address: %02x:%02x:%02x:%02x:%02x:%02x<br/>" |
no2chem | 0:83f7908c81b1 | 65 | "mbed IP Address: %s<br/>", |
no2chem | 0:83f7908c81b1 | 66 | ctime(&seconds), |
no2chem | 0:83f7908c81b1 | 67 | (char*) netif->hwaddr[0], |
no2chem | 0:83f7908c81b1 | 68 | (char*) netif->hwaddr[1], |
no2chem | 0:83f7908c81b1 | 69 | (char*) netif->hwaddr[2], |
no2chem | 0:83f7908c81b1 | 70 | (char*) netif->hwaddr[3], |
no2chem | 0:83f7908c81b1 | 71 | (char*) netif->hwaddr[4], |
no2chem | 0:83f7908c81b1 | 72 | (char*) netif->hwaddr[5], |
no2chem | 0:83f7908c81b1 | 73 | inet_ntoa(*(struct in_addr*)&(netif->ip_addr)) |
no2chem | 0:83f7908c81b1 | 74 | ); |
no2chem | 0:83f7908c81b1 | 75 | sprintf(buffer, testPage, temp); |
no2chem | 0:83f7908c81b1 | 76 | if (tcp_write(pcb, (void *)buffer, strlen(buffer), 1) == ERR_OK) { |
no2chem | 0:83f7908c81b1 | 77 | tcp_output(pcb); |
no2chem | 0:83f7908c81b1 | 78 | printf("Closing connection...\r\n"); |
no2chem | 0:83f7908c81b1 | 79 | tcp_close(pcb); |
no2chem | 0:83f7908c81b1 | 80 | } |
no2chem | 0:83f7908c81b1 | 81 | } |
no2chem | 0:83f7908c81b1 | 82 | else |
no2chem | 0:83f7908c81b1 | 83 | { |
no2chem | 0:83f7908c81b1 | 84 | printf("Non GET request...\r\nRequest:\r\n%s\r\n", data); |
no2chem | 0:83f7908c81b1 | 85 | } |
no2chem | 0:83f7908c81b1 | 86 | |
no2chem | 0:83f7908c81b1 | 87 | pbuf_free(p); |
no2chem | 0:83f7908c81b1 | 88 | } |
no2chem | 0:83f7908c81b1 | 89 | |
no2chem | 0:83f7908c81b1 | 90 | else { |
no2chem | 0:83f7908c81b1 | 91 | /* No data arrived */ |
no2chem | 0:83f7908c81b1 | 92 | /* That means the client closes the connection and sent us a packet with FIN flag set to 1. */ |
no2chem | 0:83f7908c81b1 | 93 | /* We have to cleanup and destroy out TCPConnection. */ |
no2chem | 0:83f7908c81b1 | 94 | printf("Connection closed by client.\r\n"); |
no2chem | 0:83f7908c81b1 | 95 | pbuf_free(p); |
no2chem | 0:83f7908c81b1 | 96 | } |
no2chem | 0:83f7908c81b1 | 97 | /* Don't panic! Everything is fine. */ |
no2chem | 0:83f7908c81b1 | 98 | ledTCP80 = false; |
no2chem | 0:83f7908c81b1 | 99 | return ERR_OK; |
no2chem | 0:83f7908c81b1 | 100 | } |
no2chem | 0:83f7908c81b1 | 101 | /* Accept an incomming call on the registered port */ |
no2chem | 0:83f7908c81b1 | 102 | err_t accept_callback(void *arg, struct tcp_pcb *npcb, err_t err) { |
no2chem | 0:83f7908c81b1 | 103 | LWIP_UNUSED_ARG(arg); |
no2chem | 0:83f7908c81b1 | 104 | /* Subscribe a receive callback function */ |
no2chem | 0:83f7908c81b1 | 105 | tcp_recv(npcb, &recv_callback); |
no2chem | 0:83f7908c81b1 | 106 | /* Don't panic! Everything is fine. */ |
no2chem | 0:83f7908c81b1 | 107 | return ERR_OK; |
no2chem | 0:83f7908c81b1 | 108 | } |
no2chem | 0:83f7908c81b1 | 109 | |
no2chem | 0:83f7908c81b1 | 110 | void stageblinker() |
no2chem | 0:83f7908c81b1 | 111 | { |
no2chem | 0:83f7908c81b1 | 112 | switch (stage) |
no2chem | 0:83f7908c81b1 | 113 | { |
no2chem | 0:83f7908c81b1 | 114 | case 0: |
no2chem | 0:83f7908c81b1 | 115 | ledStage0 = !ledStage0; |
no2chem | 0:83f7908c81b1 | 116 | ledStage1 = false; |
no2chem | 0:83f7908c81b1 | 117 | ledStage2 = false; |
no2chem | 0:83f7908c81b1 | 118 | break; |
no2chem | 0:83f7908c81b1 | 119 | case 1: |
no2chem | 0:83f7908c81b1 | 120 | ledStage0 = true; |
no2chem | 0:83f7908c81b1 | 121 | ledStage1 = !ledStage1; |
no2chem | 0:83f7908c81b1 | 122 | ledStage2 = false; |
no2chem | 0:83f7908c81b1 | 123 | break; |
no2chem | 0:83f7908c81b1 | 124 | case 2: |
no2chem | 0:83f7908c81b1 | 125 | ledStage0 = true; |
no2chem | 0:83f7908c81b1 | 126 | ledStage1 = true; |
no2chem | 0:83f7908c81b1 | 127 | ledStage2 = true; |
no2chem | 0:83f7908c81b1 | 128 | stage_blinker.detach(); |
no2chem | 0:83f7908c81b1 | 129 | break; |
no2chem | 0:83f7908c81b1 | 130 | } |
no2chem | 0:83f7908c81b1 | 131 | } |
no2chem | 0:83f7908c81b1 | 132 | |
no2chem | 0:83f7908c81b1 | 133 | int main() { |
no2chem | 0:83f7908c81b1 | 134 | printf("mBed Ethernet Tester 1.0\r\nStarting Up...\r\n"); |
no2chem | 0:83f7908c81b1 | 135 | stage = 0; |
no2chem | 0:83f7908c81b1 | 136 | struct netif *netif = &netif_data; |
no2chem | 0:83f7908c81b1 | 137 | struct ip_addr ipaddr; |
no2chem | 0:83f7908c81b1 | 138 | struct ip_addr netmask; |
no2chem | 0:83f7908c81b1 | 139 | struct ip_addr gateway; |
no2chem | 0:83f7908c81b1 | 140 | Ticker tickFast, tickSlow, tickARP, eth_tick, dns_tick, dhcp_coarse, dhcp_fine; |
no2chem | 0:83f7908c81b1 | 141 | stage_blinker.attach_us(&stageblinker, 1000*500); |
no2chem | 0:83f7908c81b1 | 142 | |
no2chem | 0:83f7908c81b1 | 143 | char *hostname = "my-mbed"; |
no2chem | 0:83f7908c81b1 | 144 | |
no2chem | 0:83f7908c81b1 | 145 | printf("Configuring device for DHCP...\r\n"); |
no2chem | 0:83f7908c81b1 | 146 | /* Start Network with DHCP */ |
no2chem | 0:83f7908c81b1 | 147 | IP4_ADDR(&netmask, 255,255,255,255); |
no2chem | 0:83f7908c81b1 | 148 | IP4_ADDR(&gateway, 0,0,0,0); |
no2chem | 0:83f7908c81b1 | 149 | IP4_ADDR(&ipaddr, 0,0,0,0); |
no2chem | 0:83f7908c81b1 | 150 | /* Initialise after configuration */ |
no2chem | 0:83f7908c81b1 | 151 | lwip_init(); |
no2chem | 0:83f7908c81b1 | 152 | netif->hwaddr_len = ETHARP_HWADDR_LEN; |
no2chem | 0:83f7908c81b1 | 153 | device_address((char *)netif->hwaddr); |
no2chem | 0:83f7908c81b1 | 154 | netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, device_init, ip_input); |
no2chem | 0:83f7908c81b1 | 155 | netif->hostname = hostname; |
no2chem | 0:83f7908c81b1 | 156 | netif_set_default(netif); |
no2chem | 0:83f7908c81b1 | 157 | dhcp_start(netif); // <-- Use DHCP |
no2chem | 0:83f7908c81b1 | 158 | |
no2chem | 0:83f7908c81b1 | 159 | /* Initialise all needed timers */ |
no2chem | 0:83f7908c81b1 | 160 | tickARP.attach_us( ðarp_tmr, ARP_TMR_INTERVAL * 1000); |
no2chem | 0:83f7908c81b1 | 161 | tickFast.attach_us(&tcp_fasttmr, TCP_FAST_INTERVAL * 1000); |
no2chem | 0:83f7908c81b1 | 162 | tickSlow.attach_us(&tcp_slowtmr, TCP_SLOW_INTERVAL * 1000); |
no2chem | 0:83f7908c81b1 | 163 | dns_tick.attach_us(&dns_tmr, DNS_TMR_INTERVAL * 1000); |
no2chem | 0:83f7908c81b1 | 164 | dhcp_coarse.attach_us(&dhcp_coarse_tmr, DHCP_COARSE_TIMER_MSECS * 1000); |
no2chem | 0:83f7908c81b1 | 165 | dhcp_fine.attach_us(&dhcp_fine_tmr, DHCP_FINE_TIMER_MSECS * 1000); |
no2chem | 0:83f7908c81b1 | 166 | stage = 1; |
no2chem | 0:83f7908c81b1 | 167 | while (!netif_is_up(netif)) { |
no2chem | 0:83f7908c81b1 | 168 | ledLink = ethernet.link(); |
no2chem | 0:83f7908c81b1 | 169 | device_poll(); |
no2chem | 0:83f7908c81b1 | 170 | } |
no2chem | 0:83f7908c81b1 | 171 | |
no2chem | 0:83f7908c81b1 | 172 | /* |
no2chem | 0:83f7908c81b1 | 173 | while (!(netif->dhcp->state == DHCP_BOUND || netif->dhcp->state == DHCP_PERMANENT)) |
no2chem | 0:83f7908c81b1 | 174 | { |
no2chem | 0:83f7908c81b1 | 175 | ledLink = ethernet.link(); |
no2chem | 0:83f7908c81b1 | 176 | device_poll(); |
no2chem | 0:83f7908c81b1 | 177 | //printf("Waiting for DHCP response, state = %d\r\n", netif->dhcp->state); |
no2chem | 0:83f7908c81b1 | 178 | //wait_ms(100); |
no2chem | 0:83f7908c81b1 | 179 | } |
no2chem | 0:83f7908c81b1 | 180 | */ |
no2chem | 0:83f7908c81b1 | 181 | stage = 2; |
no2chem | 0:83f7908c81b1 | 182 | printf("Interface is up, local IP is %s\r\n", |
no2chem | 0:83f7908c81b1 | 183 | inet_ntoa(*(struct in_addr*)&(netif->ip_addr))); |
no2chem | 0:83f7908c81b1 | 184 | |
no2chem | 0:83f7908c81b1 | 185 | printf("Starting Web Server...\r\n"); |
no2chem | 0:83f7908c81b1 | 186 | |
no2chem | 0:83f7908c81b1 | 187 | /* Bind a function to a tcp port */ |
no2chem | 0:83f7908c81b1 | 188 | struct tcp_pcb *pcb = tcp_new(); |
no2chem | 0:83f7908c81b1 | 189 | if (tcp_bind(pcb, IP_ADDR_ANY, 80) == ERR_OK) { |
no2chem | 0:83f7908c81b1 | 190 | pcb = tcp_listen(pcb); |
no2chem | 0:83f7908c81b1 | 191 | tcp_accept(pcb, &accept_callback); |
no2chem | 0:83f7908c81b1 | 192 | } |
no2chem | 0:83f7908c81b1 | 193 | |
no2chem | 0:83f7908c81b1 | 194 | printf("Waiting for connection...\r\n"); |
no2chem | 0:83f7908c81b1 | 195 | while(1) { |
no2chem | 0:83f7908c81b1 | 196 | device_poll(); |
no2chem | 0:83f7908c81b1 | 197 | ledLink = ethernet.link(); |
no2chem | 0:83f7908c81b1 | 198 | } |
no2chem | 0:83f7908c81b1 | 199 | } |