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.

Dependencies:   mbed lwip

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( &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);

    // 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();
    }
}