Used in Live Traffic Update Nokia LCD Display Project

Fork of NetServices by Segundo Equipo

Committer:
rrajan8
Date:
Wed Mar 06 19:07:23 2013 +0000
Revision:
8:92b57208ab99
Parent:
0:ac1725ba162c
This project utilizes mbed's networking features to display live traffic updates on the Nokia LCD using the MapQuest API's Traffic Web Service.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
segundo 0:ac1725ba162c 1 /**
segundo 0:ac1725ba162c 2 * @file
segundo 0:ac1725ba162c 3 * Ethernet Interface Skeleton
segundo 0:ac1725ba162c 4 *
segundo 0:ac1725ba162c 5 */
segundo 0:ac1725ba162c 6
segundo 0:ac1725ba162c 7 /*
segundo 0:ac1725ba162c 8 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
segundo 0:ac1725ba162c 9 * All rights reserved.
segundo 0:ac1725ba162c 10 *
segundo 0:ac1725ba162c 11 * Redistribution and use in source and binary forms, with or without modification,
segundo 0:ac1725ba162c 12 * are permitted provided that the following conditions are met:
segundo 0:ac1725ba162c 13 *
segundo 0:ac1725ba162c 14 * 1. Redistributions of source code must retain the above copyright notice,
segundo 0:ac1725ba162c 15 * this list of conditions and the following disclaimer.
segundo 0:ac1725ba162c 16 * 2. Redistributions in binary form must reproduce the above copyright notice,
segundo 0:ac1725ba162c 17 * this list of conditions and the following disclaimer in the documentation
segundo 0:ac1725ba162c 18 * and/or other materials provided with the distribution.
segundo 0:ac1725ba162c 19 * 3. The name of the author may not be used to endorse or promote products
segundo 0:ac1725ba162c 20 * derived from this software without specific prior written permission.
segundo 0:ac1725ba162c 21 *
segundo 0:ac1725ba162c 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
segundo 0:ac1725ba162c 23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
segundo 0:ac1725ba162c 24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
segundo 0:ac1725ba162c 25 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
segundo 0:ac1725ba162c 26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
segundo 0:ac1725ba162c 27 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
segundo 0:ac1725ba162c 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
segundo 0:ac1725ba162c 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
segundo 0:ac1725ba162c 30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
segundo 0:ac1725ba162c 31 * OF SUCH DAMAGE.
segundo 0:ac1725ba162c 32 *
segundo 0:ac1725ba162c 33 * This file is part of the lwIP TCP/IP stack.
segundo 0:ac1725ba162c 34 *
segundo 0:ac1725ba162c 35 * Author: Adam Dunkels <adam@sics.se>
segundo 0:ac1725ba162c 36 *
segundo 0:ac1725ba162c 37 */
segundo 0:ac1725ba162c 38
segundo 0:ac1725ba162c 39 /*
segundo 0:ac1725ba162c 40 * This file is a skeleton for developing Ethernet network interface
segundo 0:ac1725ba162c 41 * drivers for lwIP. Add code to the low_level functions and do a
segundo 0:ac1725ba162c 42 * search-and-replace for the word "ethernetif" to replace it with
segundo 0:ac1725ba162c 43 * something that better describes your network interface.
segundo 0:ac1725ba162c 44 */
segundo 0:ac1725ba162c 45
segundo 0:ac1725ba162c 46 #include "lwip/opt.h"
segundo 0:ac1725ba162c 47
segundo 0:ac1725ba162c 48 #if 0 /* don't build, this is only a skeleton, see previous comment */
segundo 0:ac1725ba162c 49
segundo 0:ac1725ba162c 50 #include "lwip/def.h"
segundo 0:ac1725ba162c 51 #include "lwip/mem.h"
segundo 0:ac1725ba162c 52 #include "lwip/pbuf.h"
segundo 0:ac1725ba162c 53 #include "lwip/sys.h"
segundo 0:ac1725ba162c 54 #include <lwip/stats.h>
segundo 0:ac1725ba162c 55 #include <lwip/snmp.h>
segundo 0:ac1725ba162c 56 #include "netif/etharp.h"
segundo 0:ac1725ba162c 57 #include "netif/ppp_oe.h"
segundo 0:ac1725ba162c 58
segundo 0:ac1725ba162c 59 /* Define those to better describe your network interface. */
segundo 0:ac1725ba162c 60 #define IFNAME0 'e'
segundo 0:ac1725ba162c 61 #define IFNAME1 'n'
segundo 0:ac1725ba162c 62
segundo 0:ac1725ba162c 63 /**
segundo 0:ac1725ba162c 64 * Helper struct to hold private data used to operate your ethernet interface.
segundo 0:ac1725ba162c 65 * Keeping the ethernet address of the MAC in this struct is not necessary
segundo 0:ac1725ba162c 66 * as it is already kept in the struct netif.
segundo 0:ac1725ba162c 67 * But this is only an example, anyway...
segundo 0:ac1725ba162c 68 */
segundo 0:ac1725ba162c 69 struct ethernetif {
segundo 0:ac1725ba162c 70 struct eth_addr *ethaddr;
segundo 0:ac1725ba162c 71 /* Add whatever per-interface state that is needed here. */
segundo 0:ac1725ba162c 72 };
segundo 0:ac1725ba162c 73
segundo 0:ac1725ba162c 74 /* Forward declarations. */
segundo 0:ac1725ba162c 75 static void ethernetif_input(struct netif *netif);
segundo 0:ac1725ba162c 76
segundo 0:ac1725ba162c 77 /**
segundo 0:ac1725ba162c 78 * In this function, the hardware should be initialized.
segundo 0:ac1725ba162c 79 * Called from ethernetif_init().
segundo 0:ac1725ba162c 80 *
segundo 0:ac1725ba162c 81 * @param netif the already initialized lwip network interface structure
segundo 0:ac1725ba162c 82 * for this ethernetif
segundo 0:ac1725ba162c 83 */
segundo 0:ac1725ba162c 84 static void
segundo 0:ac1725ba162c 85 low_level_init(struct netif *netif)
segundo 0:ac1725ba162c 86 {
segundo 0:ac1725ba162c 87 struct ethernetif *ethernetif = netif->state;
segundo 0:ac1725ba162c 88
segundo 0:ac1725ba162c 89 /* set MAC hardware address length */
segundo 0:ac1725ba162c 90 netif->hwaddr_len = ETHARP_HWADDR_LEN;
segundo 0:ac1725ba162c 91
segundo 0:ac1725ba162c 92 /* set MAC hardware address */
segundo 0:ac1725ba162c 93 netif->hwaddr[0] = ;
segundo 0:ac1725ba162c 94 ...
segundo 0:ac1725ba162c 95 netif->hwaddr[5] = ;
segundo 0:ac1725ba162c 96
segundo 0:ac1725ba162c 97 /* maximum transfer unit */
segundo 0:ac1725ba162c 98 netif->mtu = 1500;
segundo 0:ac1725ba162c 99
segundo 0:ac1725ba162c 100 /* device capabilities */
segundo 0:ac1725ba162c 101 /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
segundo 0:ac1725ba162c 102 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
segundo 0:ac1725ba162c 103
segundo 0:ac1725ba162c 104 /* Do whatever else is needed to initialize interface. */
segundo 0:ac1725ba162c 105 }
segundo 0:ac1725ba162c 106
segundo 0:ac1725ba162c 107 /**
segundo 0:ac1725ba162c 108 * This function should do the actual transmission of the packet. The packet is
segundo 0:ac1725ba162c 109 * contained in the pbuf that is passed to the function. This pbuf
segundo 0:ac1725ba162c 110 * might be chained.
segundo 0:ac1725ba162c 111 *
segundo 0:ac1725ba162c 112 * @param netif the lwip network interface structure for this ethernetif
segundo 0:ac1725ba162c 113 * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
segundo 0:ac1725ba162c 114 * @return ERR_OK if the packet could be sent
segundo 0:ac1725ba162c 115 * an err_t value if the packet couldn't be sent
segundo 0:ac1725ba162c 116 *
segundo 0:ac1725ba162c 117 * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
segundo 0:ac1725ba162c 118 * strange results. You might consider waiting for space in the DMA queue
segundo 0:ac1725ba162c 119 * to become availale since the stack doesn't retry to send a packet
segundo 0:ac1725ba162c 120 * dropped because of memory failure (except for the TCP timers).
segundo 0:ac1725ba162c 121 */
segundo 0:ac1725ba162c 122
segundo 0:ac1725ba162c 123 static err_t
segundo 0:ac1725ba162c 124 low_level_output(struct netif *netif, struct pbuf *p)
segundo 0:ac1725ba162c 125 {
segundo 0:ac1725ba162c 126 struct ethernetif *ethernetif = netif->state;
segundo 0:ac1725ba162c 127 struct pbuf *q;
segundo 0:ac1725ba162c 128
segundo 0:ac1725ba162c 129 initiate transfer();
segundo 0:ac1725ba162c 130
segundo 0:ac1725ba162c 131 #if ETH_PAD_SIZE
segundo 0:ac1725ba162c 132 pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
segundo 0:ac1725ba162c 133 #endif
segundo 0:ac1725ba162c 134
segundo 0:ac1725ba162c 135 for(q = p; q != NULL; q = q->next) {
segundo 0:ac1725ba162c 136 /* Send the data from the pbuf to the interface, one pbuf at a
segundo 0:ac1725ba162c 137 time. The size of the data in each pbuf is kept in the ->len
segundo 0:ac1725ba162c 138 variable. */
segundo 0:ac1725ba162c 139 send data from(q->payload, q->len);
segundo 0:ac1725ba162c 140 }
segundo 0:ac1725ba162c 141
segundo 0:ac1725ba162c 142 signal that packet should be sent();
segundo 0:ac1725ba162c 143
segundo 0:ac1725ba162c 144 #if ETH_PAD_SIZE
segundo 0:ac1725ba162c 145 pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
segundo 0:ac1725ba162c 146 #endif
segundo 0:ac1725ba162c 147
segundo 0:ac1725ba162c 148 LINK_STATS_INC(link.xmit);
segundo 0:ac1725ba162c 149
segundo 0:ac1725ba162c 150 return ERR_OK;
segundo 0:ac1725ba162c 151 }
segundo 0:ac1725ba162c 152
segundo 0:ac1725ba162c 153 /**
segundo 0:ac1725ba162c 154 * Should allocate a pbuf and transfer the bytes of the incoming
segundo 0:ac1725ba162c 155 * packet from the interface into the pbuf.
segundo 0:ac1725ba162c 156 *
segundo 0:ac1725ba162c 157 * @param netif the lwip network interface structure for this ethernetif
segundo 0:ac1725ba162c 158 * @return a pbuf filled with the received packet (including MAC header)
segundo 0:ac1725ba162c 159 * NULL on memory error
segundo 0:ac1725ba162c 160 */
segundo 0:ac1725ba162c 161 static struct pbuf *
segundo 0:ac1725ba162c 162 low_level_input(struct netif *netif)
segundo 0:ac1725ba162c 163 {
segundo 0:ac1725ba162c 164 struct ethernetif *ethernetif = netif->state;
segundo 0:ac1725ba162c 165 struct pbuf *p, *q;
segundo 0:ac1725ba162c 166 u16_t len;
segundo 0:ac1725ba162c 167
segundo 0:ac1725ba162c 168 /* Obtain the size of the packet and put it into the "len"
segundo 0:ac1725ba162c 169 variable. */
segundo 0:ac1725ba162c 170 len = ;
segundo 0:ac1725ba162c 171
segundo 0:ac1725ba162c 172 #if ETH_PAD_SIZE
segundo 0:ac1725ba162c 173 len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
segundo 0:ac1725ba162c 174 #endif
segundo 0:ac1725ba162c 175
segundo 0:ac1725ba162c 176 /* We allocate a pbuf chain of pbufs from the pool. */
segundo 0:ac1725ba162c 177 p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
segundo 0:ac1725ba162c 178
segundo 0:ac1725ba162c 179 if (p != NULL) {
segundo 0:ac1725ba162c 180
segundo 0:ac1725ba162c 181 #if ETH_PAD_SIZE
segundo 0:ac1725ba162c 182 pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
segundo 0:ac1725ba162c 183 #endif
segundo 0:ac1725ba162c 184
segundo 0:ac1725ba162c 185 /* We iterate over the pbuf chain until we have read the entire
segundo 0:ac1725ba162c 186 * packet into the pbuf. */
segundo 0:ac1725ba162c 187 for(q = p; q != NULL; q = q->next) {
segundo 0:ac1725ba162c 188 /* Read enough bytes to fill this pbuf in the chain. The
segundo 0:ac1725ba162c 189 * available data in the pbuf is given by the q->len
segundo 0:ac1725ba162c 190 * variable.
segundo 0:ac1725ba162c 191 * This does not necessarily have to be a memcpy, you can also preallocate
segundo 0:ac1725ba162c 192 * pbufs for a DMA-enabled MAC and after receiving truncate it to the
segundo 0:ac1725ba162c 193 * actually received size. In this case, ensure the tot_len member of the
segundo 0:ac1725ba162c 194 * pbuf is the sum of the chained pbuf len members.
segundo 0:ac1725ba162c 195 */
segundo 0:ac1725ba162c 196 read data into(q->payload, q->len);
segundo 0:ac1725ba162c 197 }
segundo 0:ac1725ba162c 198 acknowledge that packet has been read();
segundo 0:ac1725ba162c 199
segundo 0:ac1725ba162c 200 #if ETH_PAD_SIZE
segundo 0:ac1725ba162c 201 pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
segundo 0:ac1725ba162c 202 #endif
segundo 0:ac1725ba162c 203
segundo 0:ac1725ba162c 204 LINK_STATS_INC(link.recv);
segundo 0:ac1725ba162c 205 } else {
segundo 0:ac1725ba162c 206 drop packet();
segundo 0:ac1725ba162c 207 LINK_STATS_INC(link.memerr);
segundo 0:ac1725ba162c 208 LINK_STATS_INC(link.drop);
segundo 0:ac1725ba162c 209 }
segundo 0:ac1725ba162c 210
segundo 0:ac1725ba162c 211 return p;
segundo 0:ac1725ba162c 212 }
segundo 0:ac1725ba162c 213
segundo 0:ac1725ba162c 214 /**
segundo 0:ac1725ba162c 215 * This function should be called when a packet is ready to be read
segundo 0:ac1725ba162c 216 * from the interface. It uses the function low_level_input() that
segundo 0:ac1725ba162c 217 * should handle the actual reception of bytes from the network
segundo 0:ac1725ba162c 218 * interface. Then the type of the received packet is determined and
segundo 0:ac1725ba162c 219 * the appropriate input function is called.
segundo 0:ac1725ba162c 220 *
segundo 0:ac1725ba162c 221 * @param netif the lwip network interface structure for this ethernetif
segundo 0:ac1725ba162c 222 */
segundo 0:ac1725ba162c 223 static void
segundo 0:ac1725ba162c 224 ethernetif_input(struct netif *netif)
segundo 0:ac1725ba162c 225 {
segundo 0:ac1725ba162c 226 struct ethernetif *ethernetif;
segundo 0:ac1725ba162c 227 struct eth_hdr *ethhdr;
segundo 0:ac1725ba162c 228 struct pbuf *p;
segundo 0:ac1725ba162c 229
segundo 0:ac1725ba162c 230 ethernetif = netif->state;
segundo 0:ac1725ba162c 231
segundo 0:ac1725ba162c 232 /* move received packet into a new pbuf */
segundo 0:ac1725ba162c 233 p = low_level_input(netif);
segundo 0:ac1725ba162c 234 /* no packet could be read, silently ignore this */
segundo 0:ac1725ba162c 235 if (p == NULL) return;
segundo 0:ac1725ba162c 236 /* points to packet payload, which starts with an Ethernet header */
segundo 0:ac1725ba162c 237 ethhdr = p->payload;
segundo 0:ac1725ba162c 238
segundo 0:ac1725ba162c 239 switch (htons(ethhdr->type)) {
segundo 0:ac1725ba162c 240 /* IP or ARP packet? */
segundo 0:ac1725ba162c 241 case ETHTYPE_IP:
segundo 0:ac1725ba162c 242 case ETHTYPE_ARP:
segundo 0:ac1725ba162c 243 #if PPPOE_SUPPORT
segundo 0:ac1725ba162c 244 /* PPPoE packet? */
segundo 0:ac1725ba162c 245 case ETHTYPE_PPPOEDISC:
segundo 0:ac1725ba162c 246 case ETHTYPE_PPPOE:
segundo 0:ac1725ba162c 247 #endif /* PPPOE_SUPPORT */
segundo 0:ac1725ba162c 248 /* full packet send to tcpip_thread to process */
segundo 0:ac1725ba162c 249 if (netif->input(p, netif)!=ERR_OK)
segundo 0:ac1725ba162c 250 { LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
segundo 0:ac1725ba162c 251 pbuf_free(p);
segundo 0:ac1725ba162c 252 p = NULL;
segundo 0:ac1725ba162c 253 }
segundo 0:ac1725ba162c 254 break;
segundo 0:ac1725ba162c 255
segundo 0:ac1725ba162c 256 default:
segundo 0:ac1725ba162c 257 pbuf_free(p);
segundo 0:ac1725ba162c 258 p = NULL;
segundo 0:ac1725ba162c 259 break;
segundo 0:ac1725ba162c 260 }
segundo 0:ac1725ba162c 261 }
segundo 0:ac1725ba162c 262
segundo 0:ac1725ba162c 263 /**
segundo 0:ac1725ba162c 264 * Should be called at the beginning of the program to set up the
segundo 0:ac1725ba162c 265 * network interface. It calls the function low_level_init() to do the
segundo 0:ac1725ba162c 266 * actual setup of the hardware.
segundo 0:ac1725ba162c 267 *
segundo 0:ac1725ba162c 268 * This function should be passed as a parameter to netif_add().
segundo 0:ac1725ba162c 269 *
segundo 0:ac1725ba162c 270 * @param netif the lwip network interface structure for this ethernetif
segundo 0:ac1725ba162c 271 * @return ERR_OK if the loopif is initialized
segundo 0:ac1725ba162c 272 * ERR_MEM if private data couldn't be allocated
segundo 0:ac1725ba162c 273 * any other err_t on error
segundo 0:ac1725ba162c 274 */
segundo 0:ac1725ba162c 275 err_t
segundo 0:ac1725ba162c 276 ethernetif_init(struct netif *netif)
segundo 0:ac1725ba162c 277 {
segundo 0:ac1725ba162c 278 struct ethernetif *ethernetif;
segundo 0:ac1725ba162c 279
segundo 0:ac1725ba162c 280 LWIP_ASSERT("netif != NULL", (netif != NULL));
segundo 0:ac1725ba162c 281
segundo 0:ac1725ba162c 282 ethernetif = mem_malloc(sizeof(struct ethernetif));
segundo 0:ac1725ba162c 283 if (ethernetif == NULL) {
segundo 0:ac1725ba162c 284 LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
segundo 0:ac1725ba162c 285 return ERR_MEM;
segundo 0:ac1725ba162c 286 }
segundo 0:ac1725ba162c 287
segundo 0:ac1725ba162c 288 #if LWIP_NETIF_HOSTNAME
segundo 0:ac1725ba162c 289 /* Initialize interface hostname */
segundo 0:ac1725ba162c 290 netif->hostname = "lwip";
segundo 0:ac1725ba162c 291 #endif /* LWIP_NETIF_HOSTNAME */
segundo 0:ac1725ba162c 292
segundo 0:ac1725ba162c 293 /*
segundo 0:ac1725ba162c 294 * Initialize the snmp variables and counters inside the struct netif.
segundo 0:ac1725ba162c 295 * The last argument should be replaced with your link speed, in units
segundo 0:ac1725ba162c 296 * of bits per second.
segundo 0:ac1725ba162c 297 */
segundo 0:ac1725ba162c 298 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
segundo 0:ac1725ba162c 299
segundo 0:ac1725ba162c 300 netif->state = ethernetif;
segundo 0:ac1725ba162c 301 netif->name[0] = IFNAME0;
segundo 0:ac1725ba162c 302 netif->name[1] = IFNAME1;
segundo 0:ac1725ba162c 303 /* We directly use etharp_output() here to save a function call.
segundo 0:ac1725ba162c 304 * You can instead declare your own function an call etharp_output()
segundo 0:ac1725ba162c 305 * from it if you have to do some checks before sending (e.g. if link
segundo 0:ac1725ba162c 306 * is available...) */
segundo 0:ac1725ba162c 307 netif->output = etharp_output;
segundo 0:ac1725ba162c 308 netif->linkoutput = low_level_output;
segundo 0:ac1725ba162c 309
segundo 0:ac1725ba162c 310 ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
segundo 0:ac1725ba162c 311
segundo 0:ac1725ba162c 312 /* initialize the hardware */
segundo 0:ac1725ba162c 313 low_level_init(netif);
segundo 0:ac1725ba162c 314
segundo 0:ac1725ba162c 315 return ERR_OK;
segundo 0:ac1725ba162c 316 }
segundo 0:ac1725ba162c 317
segundo 0:ac1725ba162c 318 #endif /* 0 */