test code for our MBED board

Dependencies:   mbed lwip

Revision:
1:6877bb99aa17
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/network.c	Wed May 04 08:30:52 2011 +0000
@@ -0,0 +1,353 @@
+//#include "TCPCallbackConnection.h"
+//#include "NetServer.h"
+#include "mbed.h"
+#include "led.h"
+#include "can.h"
+#include "cmd.h"
+#include "help_data.h"
+#include "SNTPClient.h"
+#include "breakup.h"
+#include "ticker.h"
+#include "useful.h"
+
+#include "lwip/opt.h"
+#include "lwip/stats.h"
+#include "lwip/sys.h"
+#include "lwip/pbuf.h"
+#include "lwip/udp.h"
+#include "lwip/tcp.h"
+#include "lwip/dns.h"
+#include "lwip/dhcp.h"
+#include "lwip/init.h"
+#include "lwip/netif.h"
+#include "netif/etharp.h"
+#include "netif/loopif.h"
+#include "device.h"
+
+Ethernet ethernet;
+extern int net_state;
+extern char station_id;
+volatile char stage = 0;
+
+struct netif    netif_data;
+
+char *header = "HTTP/1.1 200 OK\r\n"
+                        "Content-Type: text/html\r\n"
+                        "Connection: Close\r\n\r\n"
+                        "<html>\r\n"
+                        "<head>\r\n"
+                        "<title>%s</title>\r\n"
+                        "<style type='text/css'>\r\n"
+                        "body{font-family:'Arial, sans-serif', sans-serif;font-size:.8em;background-color:#fff;}\r\n"
+                        "</style>\r\n"
+                        "</head>\r\n";
+
+char network_write_packet(struct tcp_pcb *pcb, char *buf)
+{
+    if (tcp_write(pcb, (void *)buf, strlen(buf), 1) == ERR_OK) {
+        tcp_output(pcb);
+        lprintf("Wrote packet String (Size %d bytes)OK...\n",strlen(buf));
+        return(1);
+    } else {
+        lprintf("Transission Problem (Size %d bytes), Closing connection...\n",strlen(buf));
+        tcp_close(pcb);
+        return(0);
+    }
+}
+void network_send_page(struct tcp_pcb *pcb,char *head, char *body, char *tail)
+{
+    if(network_write_packet(pcb, head)){
+        if(network_write_packet(pcb, body)){
+            if(network_write_packet(pcb, tail)){
+                tcp_close(pcb);
+            } else {
+               tcp_close(pcb);
+            }
+        } else {
+            tcp_close(pcb);
+        }
+    } else {
+        tcp_close(pcb);
+    }
+}
+int network_text_packet(struct tcp_pcb *pcb, char *buf)
+{
+    char    str[0x1200];    /* So we can take a 1024 byte string max */
+    char    c;
+    int     a = 0;          /* Input pointer */
+    int     b = 0;          /* output pointer */
+    
+    str[b]='<';
+    b++;
+    str[b]='p';
+    b++;
+    str[b]='r';
+    b++;
+    str[b]='e';
+    b++;
+    str[b]='>';
+    b++;
+    
+    while(a != strlen(buf)){
+        c = buf[a];
+        if(c=='\n'){
+            str[b]='<';
+            b++;
+            str[b]='b';
+            b++;
+            str[b]='r';
+            b++;
+            str[b]='>';
+            b++;
+            str[b]='\n';
+            b++;
+            a++;
+        } else if(c=='<') {
+            a++;
+        } else if(c=='>') {
+            a++;
+        } else {
+            str[b] = c;
+            a++;
+            b++;
+        }
+    }
+    str[b]='<';
+    b++;
+    str[b]='/';
+    b++;
+    str[b]='p';
+    b++;
+    str[b]='r';
+    b++;
+    str[b]='e';
+    b++;
+    str[b]='>';
+    b++;
+    str[b]='\0';
+    if(!network_write_packet(pcb, str)){
+        lprintf("Problem Packet is:\n%s",str);
+        tcp_close(pcb);
+        return(1);
+    }
+    return(0);
+}
+err_t recv_callback(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) 
+{
+    struct netif   *netif = &netif_data;
+    char *p1[100];   /* Used for the broke apart GET request */
+    char *p2[3];     /* Diagnostics call */
+    char *p3[10];    /* Diagnostics data */
+    char head[1024],body[1024],tail[200];
+    int  ret;
+     
+    lprintf("TCP callback from %d.%d.%d.%d\n", ip4_addr1(&(pcb->remote_ip)),ip4_addr2(&(pcb->remote_ip)),ip4_addr3(&(pcb->remote_ip)),ip4_addr4(&(pcb->remote_ip)));
+    char *data;
+    /* Check if status is ok and data is arrived. */
+    if (err == ERR_OK && p != NULL) {
+        /* Inform TCP that we have taken the data. */
+        tcp_recved(pcb, p->tot_len);
+        data = static_cast<char *>(p->payload);
+        /* If the data is a GET request we can handle it. */
+        if (strncmp(data, "GET ", 4) == 0) {
+            lprintf("Handling GET request...\r\n");
+            lprintf("Request:\r\n%s\r\n", data);
+            breakup(data,p1,'/');
+            time_t seconds = time(NULL);
+            sprintf(tail,"<br><small><A href=\"mailto:pcc@cs.york.ac.uk\">"
+                "pcc@cs.york.ac.uk</a>\n\r</small>\n\r"
+                "<small>mbed RTC time:%s</small><br/>\n\r"
+                "<a href=0>Home</a><br><br>\n\r"
+                "</body>\n\r</html>\n\r",ctime(&seconds));
+            switch(p1[2][0]){
+                case    '0'     :   /* Home Page */
+                    sprintf(head,header,"MBED Home");
+                    sprintf(body,"<h1>Petes MBED Homepage</h1>\n\r"
+                        "<a href=1>Board Type</a><br>\n\r"
+                        "<a href=2>Networking</a><br>\n\r"
+                        "<a href=3>Commands</a><br>\n\r"
+                        "<a href=4>CAN Bus</a><br>\n\r"
+                        "<a href=5>Diags</a><br>\n\r");
+                    network_send_page(pcb,head,body,tail);
+                    break;
+                case    '1'     :   /* Do something for page 1 */
+                    sprintf(head,header,"Board Type");
+                    sprintf(body,"<h1>MBED Board Data</h1>\n\r"
+                                "Philips NXP <a href=http://mbed.org/nxp/lpc1768/>LPC1768</a>"
+                                " Micro Controler <br>\n\r"
+                                "512K Flash Memory, 64K SRAM<br>\n\r"
+                                "<h4>MCP Solution gives:-</h4>\n\r"
+                                "1 * RS232 channel, 1 * CAN bus channel<br>\n\r"
+                                "Audio in and out, plus 4 analog inputs<br>\n\r"
+                                "Micro SD card slot, USB + TCPIP networking<br>\n\r"
+                                "+ I2C bus and selected I/O<br><br>\n\r"
+                                "See mbed.org for data<br>\n\r");
+                    network_send_page(pcb,head,body,tail);
+                break;
+                case    '2'     :   /* Networking */
+                    sprintf(head,header,"Network");
+                    sprintf(body,     "<h1>MBED Networking</h1>\n\r"
+                    "<h2>mbed Network Configuration</h2>\n\r"
+                    "mbed HW address: %02x:%02x:%02x:%02x:%02x:%02x<br/>\n\r"
+                    "mbed IP Address: %s<br/>\n\r"
+                    "Station: %d<br>",
+                    (char*) netif->hwaddr[0],
+                    (char*) netif->hwaddr[1],
+                    (char*) netif->hwaddr[2],
+                    (char*) netif->hwaddr[3],
+                    (char*) netif->hwaddr[4],
+                    (char*) netif->hwaddr[5],
+                    inet_ntoa(*(struct in_addr*)&(netif->ip_addr)),
+                    station_id
+                   );
+                    network_send_page(pcb,head,body,tail);
+                break;
+                case    '3'     :   /* Do something for page 3 */
+                    sprintf(head,header,"Commands");
+                    network_write_packet(pcb,head);
+                    sprintf(body,"<h1>MBED Commands</h1>\n\r");
+                    network_write_packet(pcb,body);
+                    network_text_packet(pcb,HELP_STRING);
+                    network_text_packet(pcb,HELP_STRING2);
+                    network_text_packet(pcb,HELP_STRING3);
+                    network_write_packet(pcb,tail);
+                    tcp_close(pcb);
+                break;
+                case    '4'     :   /* Do something for page 4 */
+                    sprintf(head,header,"CAN Bus<br>");
+                    network_send_page(pcb,head,body,tail);
+                break;
+                case    '5'     :   /* Diagnostics page */
+                    sprintf(head,header,"Board Diags");
+                    network_write_packet(pcb,head);
+                    /* Command handler */
+                    if(breakup(p1[2],p2,'?')>1){
+                        ret = breakup(p2[1],p3,'&');
+                        if((strcmp(p3[0],"ticker"))==0)
+                            setup_ticker();
+                        else if((strcmp(p3[0],"lcd"))==0)
+                            lcd_test(ret,p3);
+                        else
+                            lprintf("Command not found, Looking for %s\n",p3[0]);
+                    }
+                    network_write_packet(pcb,"<a href=5?ticker&1>Ticker Start</a><br>\n\r");
+                    network_write_packet(pcb,"<a href=5?lcd&1>String to LCD 1</a><br>\n\r");
+                    network_write_packet(pcb,"<a href=5?lcd&2>String to LCD 2</a><br>\n\r");
+                    network_write_packet(pcb,"<a href=5?sseg>Seven Segment driver test</a><br>\n\r");
+                    network_write_packet(pcb,tail);
+                    tcp_close(pcb);
+                    
+                break;
+                default         :
+                    sprintf(head,header,"MBED Board");
+                    sprintf(body,"<h1>404 Error</h1>\n\r");
+                    network_send_page(pcb,head,body,tail);
+                break;
+            }
+
+
+              
+        } else {
+            lprintf("Non GET request...\r\nRequest:\r\n%s\r\n", data);
+        }
+
+        pbuf_free(p);
+    }
+
+    else {
+        /* No data arrived */
+        /* That means the client closes the connection and sent us a packet with FIN flag set to 1. */
+        /* We have to cleanup and destroy out TCPConnection. */
+        lprintf("Connection closed by client.\r\n");
+        pbuf_free(p);
+    }
+    /* Don't panic! Everything is fine. */
+    return ERR_OK;
+}
+/* Accept an incomming call on the registered port */
+err_t accept_callback(void *arg, struct tcp_pcb *npcb, err_t err) {
+    LWIP_UNUSED_ARG(arg);
+    /* Subscribe a receive callback function */
+    tcp_recv(npcb, &recv_callback);
+    /* Don't panic! Everything is fine. */
+    return ERR_OK;
+}
+
+void network_init(void)
+{
+    lprintf("l\r\nNetwork Starting Up...\r\n");
+    stage = 0;
+    struct netif   *netif = &netif_data;
+    struct ip_addr  ipaddr;
+    struct ip_addr  netmask;
+    struct ip_addr  gateway;
+    Ticker tickFast, tickSlow, tickARP, eth_tick, dns_tick, dhcp_coarse, dhcp_fine;
+//    stage_blinker.attach_us(&stageblinker, 1000*500);
+
+    char *hostname = "my-mbed";
+
+    lprintf("Configuring device for DHCP...\r\n");
+    /* Start Network with DHCP */
+    IP4_ADDR(&netmask, 255,255,255,255);
+    IP4_ADDR(&gateway, 0,0,0,0);
+    IP4_ADDR(&ipaddr, 0,0,0,0);
+    /* Initialise after configuration */
+    lwip_init();
+    netif->hwaddr_len = ETHARP_HWADDR_LEN;
+    device_address((char *)netif->hwaddr);
+    netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, device_init, ip_input);
+    netif->hostname = hostname;
+    netif_set_default(netif);
+    dhcp_start(netif); // <-- Use DHCP
+
+    /* Initialise all needed timers */
+    tickARP.attach_us( &etharp_tmr,  ARP_TMR_INTERVAL  * 1000);
+    tickFast.attach_us(&tcp_fasttmr, TCP_FAST_INTERVAL * 1000);
+    tickSlow.attach_us(&tcp_slowtmr, TCP_SLOW_INTERVAL * 1000);
+    dns_tick.attach_us(&dns_tmr, DNS_TMR_INTERVAL * 1000);
+    dhcp_coarse.attach_us(&dhcp_coarse_tmr, DHCP_COARSE_TIMER_MSECS * 1000);
+    dhcp_fine.attach_us(&dhcp_fine_tmr, DHCP_FINE_TIMER_MSECS * 1000);
+    stage = 1; 
+    while (!netif_is_up(netif)) {
+        device_poll();
+    }
+
+    /*
+        while (!(netif->dhcp->state == DHCP_BOUND || netif->dhcp->state == DHCP_PERMANENT))
+        {
+            ledLink = ethernet.link();
+            device_poll();
+            //printf("Waiting for DHCP response, state = %d\r\n", netif->dhcp->state);
+            //wait_ms(100);
+            }
+        */
+    stage = 2;
+    lprintf("Interface %02x.%02x.%02x.%02x.%02x.%02x is up, local IP is %s\r\n",
+            (char*) netif->hwaddr[0],
+            (char*) netif->hwaddr[1],
+            (char*) netif->hwaddr[2],
+            (char*) netif->hwaddr[3],
+            (char*) netif->hwaddr[4],
+            (char*) netif->hwaddr[5],
+           inet_ntoa(*(struct in_addr*)&(netif->ip_addr)));
+
+    lprintf("Starting Web Server...\r\n");
+
+    /* Bind a function to a tcp port */
+    struct tcp_pcb *pcb = tcp_new();
+    if (tcp_bind(pcb, IP_ADDR_ANY, 80) == ERR_OK) {
+        pcb = tcp_listen(pcb);
+        tcp_accept(pcb, &accept_callback);
+    }
+    net_state = 1;
+    
+    lprintf("Waiting for connection...\n");
+}
+
+void network_test(void) 
+{
+    led_on(2);
+    device_poll();
+    ethernet.link();
+    led_off(2);
+}
\ No newline at end of file