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