Yuji Hosogaya / Mbed 2 deprecated RawLwip

Dependencies:   mbed lwip

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "lwip/opt.h"
00002 #include "lwip/stats.h"
00003 #include "lwip/sys.h"
00004 #include "lwip/pbuf.h"
00005 #include "lwip/udp.h"
00006 #include "lwip/tcp.h"
00007 #include "lwip/dns.h"
00008 #include "lwip/dhcp.h"
00009 #include "lwip/init.h"
00010 #include "lwip/netif.h"
00011 #include "netif/etharp.h"
00012 #include "netif/loopif.h"
00013 #include "device.h"
00014 
00015 #include "mbed.h"
00016 
00017 
00018 // ----------------------------------------------------------------------------
00019 // This part is added in order to complete compiling without errors.
00020 // ----------------------------------------------------------------------------
00021 #include "string.h"
00022 
00023 #define IFNAME0 'E'
00024 #define IFNAME1 'X'
00025 
00026 #define min(x,y) (((x)<(y))?(x):(y))
00027 
00028 extern Ethernet *eth;
00029 extern struct netif *gnetif;
00030 
00031 static err_t device_output(struct netif *netif, struct pbuf *p) {
00032   #if ETH_PAD_SIZE
00033     pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
00034   #endif
00035 
00036   do {
00037     eth->write((const char *)p->payload, p->len);
00038   } while((p = p->next)!=NULL);
00039 
00040   eth->send();
00041 
00042   #if ETH_PAD_SIZE
00043     pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
00044   #endif
00045   
00046   LINK_STATS_INC(link.xmit);
00047   return ERR_OK;
00048 }
00049 
00050 void device_poll() {
00051   struct eth_hdr *ethhdr;
00052   struct pbuf *frame, *p;
00053   int len, read;
00054 
00055   while((len = eth->receive()) != 0) {
00056       frame = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
00057       if(frame == NULL) {
00058           return;
00059       }
00060       p = frame;
00061       do {
00062          read = eth->read((char *)p->payload, p->len);
00063          p = p->next;
00064       } while(p != NULL && read != 0);
00065       
00066       #if ETH_PAD_SIZE
00067           pbuf_header(p, ETH_PAD_SIZE);
00068       #endif
00069 
00070       ethhdr = (struct eth_hdr *)(frame->payload);
00071 
00072       switch(htons(ethhdr->type)) {
00073           
00074           case ETHTYPE_IP:
00075               etharp_ip_input(gnetif, frame);
00076               pbuf_header(frame, -((s16_t) sizeof(struct eth_hdr)));
00077               gnetif->input(frame, gnetif);
00078               break;
00079           
00080           case ETHTYPE_ARP:
00081               etharp_arp_input(gnetif, (struct eth_addr *)(gnetif->hwaddr), frame);
00082               break;
00083           
00084           default:
00085               break;
00086       }
00087       pbuf_free(frame);
00088   }
00089 }
00090 
00091 err_t device_init(struct netif *netif) {
00092   LWIP_ASSERT("netif != NULL", (netif != NULL));
00093   
00094   NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 0x2EA);
00095   
00096   /* maximum transfer unit */
00097   netif->mtu = 0x2EA;
00098   
00099   /* device capabilities */
00100   /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
00101   netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
00102 
00103   netif->state = NULL;
00104   gnetif = netif;
00105 
00106   netif->name[0] = IFNAME0;
00107   netif->name[1] = IFNAME1;
00108 
00109   /* We directly use etharp_output() here to save a function call.
00110    * You can instead declare your own function an call etharp_output()
00111    * from it if you have to do some checks before sending (e.g. if link
00112    * is available...) */
00113   netif->output          = etharp_output;
00114   netif->linkoutput      = device_output;
00115 
00116   eth = new Ethernet();
00117 
00118   return ERR_OK;
00119 }
00120 
00121 void device_address(char *mac) {
00122     eth->address(mac);
00123 }
00124 
00125 // ----------------------------------------------------------------------------
00126 // The end of the part added.
00127 // ----------------------------------------------------------------------------
00128 
00129 
00130 DigitalOut led(LED1);
00131 
00132 /* Struct with hold the Ethernet Data */
00133 struct netif    netif_data;
00134 
00135 /* Every time called if a packet is received for a */
00136 /* TCPConnection which registerd this Callback. */
00137 err_t recv_callback(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) {
00138     printf("recv_callback\n");
00139     if (p==NULL) {
00140         printf("Connection closed by server!\n");
00141         return ERR_OK;
00142     }
00143 
00144     while (p) {
00145         char * ch = (char*)p->payload;
00146         printf("\n>>>>>>>>>>>>\n");
00147         for (int i=0; i < p->len; i++) {
00148             printf("%c", ch[i]);
00149         }
00150         printf("\n<<<<<<<<<<<<\n");
00151         p = p->next;
00152     }
00153     tcp_recved(pcb, p->tot_len);
00154     pbuf_free(p);
00155     return ERR_OK;
00156 }
00157 
00158 /* Connection etablished, lets try to get a http page */
00159 err_t connected_callback(void *arg, struct tcp_pcb *pcb, err_t err) {
00160     tcp_recv(pcb, &recv_callback);
00161     printf("Connected Callback!\n");
00162     char msg[] = "GET / HTTP/1.1\r\nHost: www.google.co.uk\r\n\r\n";
00163     if (tcp_write(pcb, msg, strlen(msg), 1) != ERR_OK) {
00164         error("Could not write", 0);
00165     }
00166     return ERR_OK;
00167 }
00168 
00169 int main(void) {
00170     /* Create and initialise variables */
00171     struct netif   *netif = &netif_data;
00172     struct ip_addr  ipaddr;
00173     struct ip_addr  target;
00174     struct ip_addr  netmask;
00175     struct ip_addr  gateway;
00176 
00177     Ticker tickFast, tickSlow, tickARP, eth_tick, dns_tick, dhcp_coarse, dhcp_fine;
00178     char *hostname = "mbed-c3p0";
00179 
00180     /* Start Network with DHCP */
00181     IP4_ADDR(&netmask, 255,255,255,255);
00182     IP4_ADDR(&gateway, 0,0,0,0);
00183     IP4_ADDR(&ipaddr, 0,0,0,0);
00184     IP4_ADDR(&target, 209,85,229,147); // www.google.co.uk
00185 
00186     /* Initialise after configuration */
00187     lwip_init();
00188 
00189     netif->hwaddr_len = ETHARP_HWADDR_LEN;
00190     device_address((char *)netif->hwaddr);
00191 
00192     netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, device_init, ip_input);
00193     netif->hostname = hostname;
00194     netif_set_default(netif);
00195     dhcp_start(netif); // <-- Use DHCP
00196 
00197     /* Initialise all needed timers */
00198     tickARP.attach_us( &etharp_tmr,  ARP_TMR_INTERVAL  * 1000);
00199     tickFast.attach_us(&tcp_fasttmr, TCP_FAST_INTERVAL * 1000);
00200     tickSlow.attach_us(&tcp_slowtmr, TCP_SLOW_INTERVAL * 1000);
00201     dns_tick.attach_us(&dns_tmr, DNS_TMR_INTERVAL * 1000);
00202     dhcp_coarse.attach_us(&dhcp_coarse_tmr, DHCP_COARSE_TIMER_MSECS * 1000);
00203     dhcp_fine.attach_us(&dhcp_fine_tmr, DHCP_FINE_TIMER_MSECS * 1000);
00204 
00205     // Wait for an IP Address
00206     while (!netif_is_up(netif)) {
00207         device_poll();
00208     }
00209 
00210     /* Connect do google */
00211     struct tcp_pcb *pcb = tcp_new();
00212     tcp_connect(pcb, &target, 80, &connected_callback);
00213 
00214     /* Give the signal that we are ready */
00215     printf("entering while loop\n");
00216     while (1) {
00217         led = !led;
00218         wait(0.1);
00219         device_poll();
00220     }
00221 }