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@0:d3c85ea81493, 2012-03-03 (annotated)
- Committer:
- paleskyjp
- Date:
- Sat Mar 03 23:57:55 2012 +0000
- Revision:
- 0:d3c85ea81493
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
paleskyjp | 0:d3c85ea81493 | 1 | #include "lwip/opt.h" |
paleskyjp | 0:d3c85ea81493 | 2 | #include "lwip/stats.h" |
paleskyjp | 0:d3c85ea81493 | 3 | #include "lwip/sys.h" |
paleskyjp | 0:d3c85ea81493 | 4 | #include "lwip/pbuf.h" |
paleskyjp | 0:d3c85ea81493 | 5 | #include "lwip/udp.h" |
paleskyjp | 0:d3c85ea81493 | 6 | #include "lwip/tcp.h" |
paleskyjp | 0:d3c85ea81493 | 7 | #include "lwip/dns.h" |
paleskyjp | 0:d3c85ea81493 | 8 | #include "lwip/dhcp.h" |
paleskyjp | 0:d3c85ea81493 | 9 | #include "lwip/init.h" |
paleskyjp | 0:d3c85ea81493 | 10 | #include "lwip/netif.h" |
paleskyjp | 0:d3c85ea81493 | 11 | #include "netif/etharp.h" |
paleskyjp | 0:d3c85ea81493 | 12 | #include "netif/loopif.h" |
paleskyjp | 0:d3c85ea81493 | 13 | #include "device.h" |
paleskyjp | 0:d3c85ea81493 | 14 | |
paleskyjp | 0:d3c85ea81493 | 15 | #include "mbed.h" |
paleskyjp | 0:d3c85ea81493 | 16 | |
paleskyjp | 0:d3c85ea81493 | 17 | |
paleskyjp | 0:d3c85ea81493 | 18 | // ---------------------------------------------------------------------------- |
paleskyjp | 0:d3c85ea81493 | 19 | // This part is added in order to complete compiling without errors. |
paleskyjp | 0:d3c85ea81493 | 20 | // ---------------------------------------------------------------------------- |
paleskyjp | 0:d3c85ea81493 | 21 | #include "string.h" |
paleskyjp | 0:d3c85ea81493 | 22 | |
paleskyjp | 0:d3c85ea81493 | 23 | #define IFNAME0 'E' |
paleskyjp | 0:d3c85ea81493 | 24 | #define IFNAME1 'X' |
paleskyjp | 0:d3c85ea81493 | 25 | |
paleskyjp | 0:d3c85ea81493 | 26 | #define min(x,y) (((x)<(y))?(x):(y)) |
paleskyjp | 0:d3c85ea81493 | 27 | |
paleskyjp | 0:d3c85ea81493 | 28 | extern Ethernet *eth; |
paleskyjp | 0:d3c85ea81493 | 29 | extern struct netif *gnetif; |
paleskyjp | 0:d3c85ea81493 | 30 | |
paleskyjp | 0:d3c85ea81493 | 31 | static err_t device_output(struct netif *netif, struct pbuf *p) { |
paleskyjp | 0:d3c85ea81493 | 32 | #if ETH_PAD_SIZE |
paleskyjp | 0:d3c85ea81493 | 33 | pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ |
paleskyjp | 0:d3c85ea81493 | 34 | #endif |
paleskyjp | 0:d3c85ea81493 | 35 | |
paleskyjp | 0:d3c85ea81493 | 36 | do { |
paleskyjp | 0:d3c85ea81493 | 37 | eth->write((const char *)p->payload, p->len); |
paleskyjp | 0:d3c85ea81493 | 38 | } while((p = p->next)!=NULL); |
paleskyjp | 0:d3c85ea81493 | 39 | |
paleskyjp | 0:d3c85ea81493 | 40 | eth->send(); |
paleskyjp | 0:d3c85ea81493 | 41 | |
paleskyjp | 0:d3c85ea81493 | 42 | #if ETH_PAD_SIZE |
paleskyjp | 0:d3c85ea81493 | 43 | pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ |
paleskyjp | 0:d3c85ea81493 | 44 | #endif |
paleskyjp | 0:d3c85ea81493 | 45 | |
paleskyjp | 0:d3c85ea81493 | 46 | LINK_STATS_INC(link.xmit); |
paleskyjp | 0:d3c85ea81493 | 47 | return ERR_OK; |
paleskyjp | 0:d3c85ea81493 | 48 | } |
paleskyjp | 0:d3c85ea81493 | 49 | |
paleskyjp | 0:d3c85ea81493 | 50 | void device_poll() { |
paleskyjp | 0:d3c85ea81493 | 51 | struct eth_hdr *ethhdr; |
paleskyjp | 0:d3c85ea81493 | 52 | struct pbuf *frame, *p; |
paleskyjp | 0:d3c85ea81493 | 53 | int len, read; |
paleskyjp | 0:d3c85ea81493 | 54 | |
paleskyjp | 0:d3c85ea81493 | 55 | while((len = eth->receive()) != 0) { |
paleskyjp | 0:d3c85ea81493 | 56 | frame = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); |
paleskyjp | 0:d3c85ea81493 | 57 | if(frame == NULL) { |
paleskyjp | 0:d3c85ea81493 | 58 | return; |
paleskyjp | 0:d3c85ea81493 | 59 | } |
paleskyjp | 0:d3c85ea81493 | 60 | p = frame; |
paleskyjp | 0:d3c85ea81493 | 61 | do { |
paleskyjp | 0:d3c85ea81493 | 62 | read = eth->read((char *)p->payload, p->len); |
paleskyjp | 0:d3c85ea81493 | 63 | p = p->next; |
paleskyjp | 0:d3c85ea81493 | 64 | } while(p != NULL && read != 0); |
paleskyjp | 0:d3c85ea81493 | 65 | |
paleskyjp | 0:d3c85ea81493 | 66 | #if ETH_PAD_SIZE |
paleskyjp | 0:d3c85ea81493 | 67 | pbuf_header(p, ETH_PAD_SIZE); |
paleskyjp | 0:d3c85ea81493 | 68 | #endif |
paleskyjp | 0:d3c85ea81493 | 69 | |
paleskyjp | 0:d3c85ea81493 | 70 | ethhdr = (struct eth_hdr *)(frame->payload); |
paleskyjp | 0:d3c85ea81493 | 71 | |
paleskyjp | 0:d3c85ea81493 | 72 | switch(htons(ethhdr->type)) { |
paleskyjp | 0:d3c85ea81493 | 73 | |
paleskyjp | 0:d3c85ea81493 | 74 | case ETHTYPE_IP: |
paleskyjp | 0:d3c85ea81493 | 75 | etharp_ip_input(gnetif, frame); |
paleskyjp | 0:d3c85ea81493 | 76 | pbuf_header(frame, -((s16_t) sizeof(struct eth_hdr))); |
paleskyjp | 0:d3c85ea81493 | 77 | gnetif->input(frame, gnetif); |
paleskyjp | 0:d3c85ea81493 | 78 | break; |
paleskyjp | 0:d3c85ea81493 | 79 | |
paleskyjp | 0:d3c85ea81493 | 80 | case ETHTYPE_ARP: |
paleskyjp | 0:d3c85ea81493 | 81 | etharp_arp_input(gnetif, (struct eth_addr *)(gnetif->hwaddr), frame); |
paleskyjp | 0:d3c85ea81493 | 82 | break; |
paleskyjp | 0:d3c85ea81493 | 83 | |
paleskyjp | 0:d3c85ea81493 | 84 | default: |
paleskyjp | 0:d3c85ea81493 | 85 | break; |
paleskyjp | 0:d3c85ea81493 | 86 | } |
paleskyjp | 0:d3c85ea81493 | 87 | pbuf_free(frame); |
paleskyjp | 0:d3c85ea81493 | 88 | } |
paleskyjp | 0:d3c85ea81493 | 89 | } |
paleskyjp | 0:d3c85ea81493 | 90 | |
paleskyjp | 0:d3c85ea81493 | 91 | err_t device_init(struct netif *netif) { |
paleskyjp | 0:d3c85ea81493 | 92 | LWIP_ASSERT("netif != NULL", (netif != NULL)); |
paleskyjp | 0:d3c85ea81493 | 93 | |
paleskyjp | 0:d3c85ea81493 | 94 | NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 0x2EA); |
paleskyjp | 0:d3c85ea81493 | 95 | |
paleskyjp | 0:d3c85ea81493 | 96 | /* maximum transfer unit */ |
paleskyjp | 0:d3c85ea81493 | 97 | netif->mtu = 0x2EA; |
paleskyjp | 0:d3c85ea81493 | 98 | |
paleskyjp | 0:d3c85ea81493 | 99 | /* device capabilities */ |
paleskyjp | 0:d3c85ea81493 | 100 | /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ |
paleskyjp | 0:d3c85ea81493 | 101 | netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; |
paleskyjp | 0:d3c85ea81493 | 102 | |
paleskyjp | 0:d3c85ea81493 | 103 | netif->state = NULL; |
paleskyjp | 0:d3c85ea81493 | 104 | gnetif = netif; |
paleskyjp | 0:d3c85ea81493 | 105 | |
paleskyjp | 0:d3c85ea81493 | 106 | netif->name[0] = IFNAME0; |
paleskyjp | 0:d3c85ea81493 | 107 | netif->name[1] = IFNAME1; |
paleskyjp | 0:d3c85ea81493 | 108 | |
paleskyjp | 0:d3c85ea81493 | 109 | /* We directly use etharp_output() here to save a function call. |
paleskyjp | 0:d3c85ea81493 | 110 | * You can instead declare your own function an call etharp_output() |
paleskyjp | 0:d3c85ea81493 | 111 | * from it if you have to do some checks before sending (e.g. if link |
paleskyjp | 0:d3c85ea81493 | 112 | * is available...) */ |
paleskyjp | 0:d3c85ea81493 | 113 | netif->output = etharp_output; |
paleskyjp | 0:d3c85ea81493 | 114 | netif->linkoutput = device_output; |
paleskyjp | 0:d3c85ea81493 | 115 | |
paleskyjp | 0:d3c85ea81493 | 116 | eth = new Ethernet(); |
paleskyjp | 0:d3c85ea81493 | 117 | |
paleskyjp | 0:d3c85ea81493 | 118 | return ERR_OK; |
paleskyjp | 0:d3c85ea81493 | 119 | } |
paleskyjp | 0:d3c85ea81493 | 120 | |
paleskyjp | 0:d3c85ea81493 | 121 | void device_address(char *mac) { |
paleskyjp | 0:d3c85ea81493 | 122 | eth->address(mac); |
paleskyjp | 0:d3c85ea81493 | 123 | } |
paleskyjp | 0:d3c85ea81493 | 124 | |
paleskyjp | 0:d3c85ea81493 | 125 | // ---------------------------------------------------------------------------- |
paleskyjp | 0:d3c85ea81493 | 126 | // The end of the part added. |
paleskyjp | 0:d3c85ea81493 | 127 | // ---------------------------------------------------------------------------- |
paleskyjp | 0:d3c85ea81493 | 128 | |
paleskyjp | 0:d3c85ea81493 | 129 | |
paleskyjp | 0:d3c85ea81493 | 130 | DigitalOut led(LED1); |
paleskyjp | 0:d3c85ea81493 | 131 | |
paleskyjp | 0:d3c85ea81493 | 132 | /* Struct with hold the Ethernet Data */ |
paleskyjp | 0:d3c85ea81493 | 133 | struct netif netif_data; |
paleskyjp | 0:d3c85ea81493 | 134 | |
paleskyjp | 0:d3c85ea81493 | 135 | /* Every time called if a packet is received for a */ |
paleskyjp | 0:d3c85ea81493 | 136 | /* TCPConnection which registerd this Callback. */ |
paleskyjp | 0:d3c85ea81493 | 137 | err_t recv_callback(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { |
paleskyjp | 0:d3c85ea81493 | 138 | printf("recv_callback\n"); |
paleskyjp | 0:d3c85ea81493 | 139 | if (p==NULL) { |
paleskyjp | 0:d3c85ea81493 | 140 | printf("Connection closed by server!\n"); |
paleskyjp | 0:d3c85ea81493 | 141 | return ERR_OK; |
paleskyjp | 0:d3c85ea81493 | 142 | } |
paleskyjp | 0:d3c85ea81493 | 143 | |
paleskyjp | 0:d3c85ea81493 | 144 | while (p) { |
paleskyjp | 0:d3c85ea81493 | 145 | char * ch = (char*)p->payload; |
paleskyjp | 0:d3c85ea81493 | 146 | printf("\n>>>>>>>>>>>>\n"); |
paleskyjp | 0:d3c85ea81493 | 147 | for (int i=0; i < p->len; i++) { |
paleskyjp | 0:d3c85ea81493 | 148 | printf("%c", ch[i]); |
paleskyjp | 0:d3c85ea81493 | 149 | } |
paleskyjp | 0:d3c85ea81493 | 150 | printf("\n<<<<<<<<<<<<\n"); |
paleskyjp | 0:d3c85ea81493 | 151 | p = p->next; |
paleskyjp | 0:d3c85ea81493 | 152 | } |
paleskyjp | 0:d3c85ea81493 | 153 | tcp_recved(pcb, p->tot_len); |
paleskyjp | 0:d3c85ea81493 | 154 | pbuf_free(p); |
paleskyjp | 0:d3c85ea81493 | 155 | return ERR_OK; |
paleskyjp | 0:d3c85ea81493 | 156 | } |
paleskyjp | 0:d3c85ea81493 | 157 | |
paleskyjp | 0:d3c85ea81493 | 158 | /* Connection etablished, lets try to get a http page */ |
paleskyjp | 0:d3c85ea81493 | 159 | err_t connected_callback(void *arg, struct tcp_pcb *pcb, err_t err) { |
paleskyjp | 0:d3c85ea81493 | 160 | tcp_recv(pcb, &recv_callback); |
paleskyjp | 0:d3c85ea81493 | 161 | printf("Connected Callback!\n"); |
paleskyjp | 0:d3c85ea81493 | 162 | char msg[] = "GET / HTTP/1.1\r\nHost: www.google.co.uk\r\n\r\n"; |
paleskyjp | 0:d3c85ea81493 | 163 | if (tcp_write(pcb, msg, strlen(msg), 1) != ERR_OK) { |
paleskyjp | 0:d3c85ea81493 | 164 | error("Could not write", 0); |
paleskyjp | 0:d3c85ea81493 | 165 | } |
paleskyjp | 0:d3c85ea81493 | 166 | return ERR_OK; |
paleskyjp | 0:d3c85ea81493 | 167 | } |
paleskyjp | 0:d3c85ea81493 | 168 | |
paleskyjp | 0:d3c85ea81493 | 169 | int main(void) { |
paleskyjp | 0:d3c85ea81493 | 170 | /* Create and initialise variables */ |
paleskyjp | 0:d3c85ea81493 | 171 | struct netif *netif = &netif_data; |
paleskyjp | 0:d3c85ea81493 | 172 | struct ip_addr ipaddr; |
paleskyjp | 0:d3c85ea81493 | 173 | struct ip_addr target; |
paleskyjp | 0:d3c85ea81493 | 174 | struct ip_addr netmask; |
paleskyjp | 0:d3c85ea81493 | 175 | struct ip_addr gateway; |
paleskyjp | 0:d3c85ea81493 | 176 | |
paleskyjp | 0:d3c85ea81493 | 177 | Ticker tickFast, tickSlow, tickARP, eth_tick, dns_tick, dhcp_coarse, dhcp_fine; |
paleskyjp | 0:d3c85ea81493 | 178 | char *hostname = "mbed-c3p0"; |
paleskyjp | 0:d3c85ea81493 | 179 | |
paleskyjp | 0:d3c85ea81493 | 180 | /* Start Network with DHCP */ |
paleskyjp | 0:d3c85ea81493 | 181 | IP4_ADDR(&netmask, 255,255,255,255); |
paleskyjp | 0:d3c85ea81493 | 182 | IP4_ADDR(&gateway, 0,0,0,0); |
paleskyjp | 0:d3c85ea81493 | 183 | IP4_ADDR(&ipaddr, 0,0,0,0); |
paleskyjp | 0:d3c85ea81493 | 184 | IP4_ADDR(&target, 209,85,229,147); // www.google.co.uk |
paleskyjp | 0:d3c85ea81493 | 185 | |
paleskyjp | 0:d3c85ea81493 | 186 | /* Initialise after configuration */ |
paleskyjp | 0:d3c85ea81493 | 187 | lwip_init(); |
paleskyjp | 0:d3c85ea81493 | 188 | |
paleskyjp | 0:d3c85ea81493 | 189 | netif->hwaddr_len = ETHARP_HWADDR_LEN; |
paleskyjp | 0:d3c85ea81493 | 190 | device_address((char *)netif->hwaddr); |
paleskyjp | 0:d3c85ea81493 | 191 | |
paleskyjp | 0:d3c85ea81493 | 192 | netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, device_init, ip_input); |
paleskyjp | 0:d3c85ea81493 | 193 | netif->hostname = hostname; |
paleskyjp | 0:d3c85ea81493 | 194 | netif_set_default(netif); |
paleskyjp | 0:d3c85ea81493 | 195 | dhcp_start(netif); // <-- Use DHCP |
paleskyjp | 0:d3c85ea81493 | 196 | |
paleskyjp | 0:d3c85ea81493 | 197 | /* Initialise all needed timers */ |
paleskyjp | 0:d3c85ea81493 | 198 | tickARP.attach_us( ðarp_tmr, ARP_TMR_INTERVAL * 1000); |
paleskyjp | 0:d3c85ea81493 | 199 | tickFast.attach_us(&tcp_fasttmr, TCP_FAST_INTERVAL * 1000); |
paleskyjp | 0:d3c85ea81493 | 200 | tickSlow.attach_us(&tcp_slowtmr, TCP_SLOW_INTERVAL * 1000); |
paleskyjp | 0:d3c85ea81493 | 201 | dns_tick.attach_us(&dns_tmr, DNS_TMR_INTERVAL * 1000); |
paleskyjp | 0:d3c85ea81493 | 202 | dhcp_coarse.attach_us(&dhcp_coarse_tmr, DHCP_COARSE_TIMER_MSECS * 1000); |
paleskyjp | 0:d3c85ea81493 | 203 | dhcp_fine.attach_us(&dhcp_fine_tmr, DHCP_FINE_TIMER_MSECS * 1000); |
paleskyjp | 0:d3c85ea81493 | 204 | |
paleskyjp | 0:d3c85ea81493 | 205 | // Wait for an IP Address |
paleskyjp | 0:d3c85ea81493 | 206 | while (!netif_is_up(netif)) { |
paleskyjp | 0:d3c85ea81493 | 207 | device_poll(); |
paleskyjp | 0:d3c85ea81493 | 208 | } |
paleskyjp | 0:d3c85ea81493 | 209 | |
paleskyjp | 0:d3c85ea81493 | 210 | /* Connect do google */ |
paleskyjp | 0:d3c85ea81493 | 211 | struct tcp_pcb *pcb = tcp_new(); |
paleskyjp | 0:d3c85ea81493 | 212 | tcp_connect(pcb, &target, 80, &connected_callback); |
paleskyjp | 0:d3c85ea81493 | 213 | |
paleskyjp | 0:d3c85ea81493 | 214 | /* Give the signal that we are ready */ |
paleskyjp | 0:d3c85ea81493 | 215 | printf("entering while loop\n"); |
paleskyjp | 0:d3c85ea81493 | 216 | while (1) { |
paleskyjp | 0:d3c85ea81493 | 217 | led = !led; |
paleskyjp | 0:d3c85ea81493 | 218 | wait(0.1); |
paleskyjp | 0:d3c85ea81493 | 219 | device_poll(); |
paleskyjp | 0:d3c85ea81493 | 220 | } |
paleskyjp | 0:d3c85ea81493 | 221 | } |