LWIP HTTP Client without any C++ wrapper. The purpose of this program is to compile the original program shown in the site below. http://mbed.org/projects/cookbook/wiki/EMAC/purehttpc Actually, the original one cannot be compiled without errors. So I modified to complete compiling.
main.cpp
- Committer:
- paleskyjp
- Date:
- 2012-03-03
- Revision:
- 0:d3c85ea81493
File content as of revision 0:d3c85ea81493:
#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" #include "mbed.h" // ---------------------------------------------------------------------------- // This part is added in order to complete compiling without errors. // ---------------------------------------------------------------------------- #include "string.h" #define IFNAME0 'E' #define IFNAME1 'X' #define min(x,y) (((x)<(y))?(x):(y)) extern Ethernet *eth; extern struct netif *gnetif; static err_t device_output(struct netif *netif, struct pbuf *p) { #if ETH_PAD_SIZE pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ #endif do { eth->write((const char *)p->payload, p->len); } while((p = p->next)!=NULL); eth->send(); #if ETH_PAD_SIZE pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ #endif LINK_STATS_INC(link.xmit); return ERR_OK; } void device_poll() { struct eth_hdr *ethhdr; struct pbuf *frame, *p; int len, read; while((len = eth->receive()) != 0) { frame = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); if(frame == NULL) { return; } p = frame; do { read = eth->read((char *)p->payload, p->len); p = p->next; } while(p != NULL && read != 0); #if ETH_PAD_SIZE pbuf_header(p, ETH_PAD_SIZE); #endif ethhdr = (struct eth_hdr *)(frame->payload); switch(htons(ethhdr->type)) { case ETHTYPE_IP: etharp_ip_input(gnetif, frame); pbuf_header(frame, -((s16_t) sizeof(struct eth_hdr))); gnetif->input(frame, gnetif); break; case ETHTYPE_ARP: etharp_arp_input(gnetif, (struct eth_addr *)(gnetif->hwaddr), frame); break; default: break; } pbuf_free(frame); } } err_t device_init(struct netif *netif) { LWIP_ASSERT("netif != NULL", (netif != NULL)); NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 0x2EA); /* maximum transfer unit */ netif->mtu = 0x2EA; /* device capabilities */ /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; netif->state = NULL; gnetif = netif; netif->name[0] = IFNAME0; netif->name[1] = IFNAME1; /* We directly use etharp_output() here to save a function call. * You can instead declare your own function an call etharp_output() * from it if you have to do some checks before sending (e.g. if link * is available...) */ netif->output = etharp_output; netif->linkoutput = device_output; eth = new Ethernet(); return ERR_OK; } void device_address(char *mac) { eth->address(mac); } // ---------------------------------------------------------------------------- // The end of the part added. // ---------------------------------------------------------------------------- DigitalOut led(LED1); /* Struct with hold the Ethernet Data */ struct netif netif_data; /* Every time called if a packet is received for a */ /* TCPConnection which registerd this Callback. */ err_t recv_callback(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { printf("recv_callback\n"); if (p==NULL) { printf("Connection closed by server!\n"); return ERR_OK; } while (p) { char * ch = (char*)p->payload; printf("\n>>>>>>>>>>>>\n"); for (int i=0; i < p->len; i++) { printf("%c", ch[i]); } printf("\n<<<<<<<<<<<<\n"); p = p->next; } tcp_recved(pcb, p->tot_len); pbuf_free(p); return ERR_OK; } /* Connection etablished, lets try to get a http page */ err_t connected_callback(void *arg, struct tcp_pcb *pcb, err_t err) { tcp_recv(pcb, &recv_callback); printf("Connected Callback!\n"); char msg[] = "GET / HTTP/1.1\r\nHost: www.google.co.uk\r\n\r\n"; if (tcp_write(pcb, msg, strlen(msg), 1) != ERR_OK) { error("Could not write", 0); } return ERR_OK; } int main(void) { /* Create and initialise variables */ struct netif *netif = &netif_data; struct ip_addr ipaddr; struct ip_addr target; struct ip_addr netmask; struct ip_addr gateway; Ticker tickFast, tickSlow, tickARP, eth_tick, dns_tick, dhcp_coarse, dhcp_fine; char *hostname = "mbed-c3p0"; /* 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); IP4_ADDR(&target, 209,85,229,147); // www.google.co.uk /* 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( ðarp_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); // Wait for an IP Address while (!netif_is_up(netif)) { device_poll(); } /* Connect do google */ struct tcp_pcb *pcb = tcp_new(); tcp_connect(pcb, &target, 80, &connected_callback); /* Give the signal that we are ready */ printf("entering while loop\n"); while (1) { led = !led; wait(0.1); device_poll(); } }