Web server based weather station using Sparkfun Weather Meters.

Dependencies:   FatFileSystem mbed WeatherMeters SDFileSystem

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers eth_drv.cpp Source File

eth_drv.cpp

00001 
00002 /*
00003 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
00004  
00005 Permission is hereby granted, free of charge, to any person obtaining a copy
00006 of this software and associated documentation files (the "Software"), to deal
00007 in the Software without restriction, including without limitation the rights
00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00009 copies of the Software, and to permit persons to whom the Software is
00010 furnished to do so, subject to the following conditions:
00011  
00012 The above copyright notice and this permission notice shall be included in
00013 all copies or substantial portions of the Software.
00014  
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00021 THE SOFTWARE.
00022 */
00023 
00024 #include "netCfg.h"
00025 #if NET_ETH
00026 
00027 #include "mbed.h"
00028 
00029 Ethernet *pEth = NULL;
00030 #ifdef __cplusplus
00031 extern "C" {
00032 #endif
00033 
00034 #include "lwip/opt.h"
00035 
00036 #include "lwip/def.h"
00037 #include "lwip/pbuf.h"
00038 #include "lwip/sys.h"
00039 #include "lwip/stats.h"
00040 #include "netif/etharp.h"
00041 #include "string.h"
00042 
00043 //#include "eth_drv.h"
00044 
00045 #define IFNAME0 'E'
00046 #define IFNAME1 'X'
00047 
00048 #define min(x,y) (((x)<(y))?(x):(y))
00049 
00050 struct netif* eth_netif;
00051 
00052 static err_t eth_output(struct netif *netif, struct pbuf *p) {
00053   #if ETH_PAD_SIZE
00054     pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
00055   #endif
00056 
00057   do {
00058     pEth->write((const char *)p->payload, p->len);
00059   } while((p = p->next)!=NULL);
00060 
00061   pEth->send();
00062 
00063   #if ETH_PAD_SIZE
00064     pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
00065   #endif
00066   
00067   LINK_STATS_INC(link.xmit);
00068   return ERR_OK;
00069 }
00070 
00071 /*
00072 void show(char *buf, int size) {
00073     printf("Destination:  %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
00074             buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
00075     printf("Source: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
00076             buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]);
00077   
00078     printf("Type %hd\n", htons((short)buf[12]));
00079     
00080    // hexview(buf, size);
00081 }
00082 */
00083 
00084 int eth_poll() {
00085   int PacketsReceived = 0;
00086   struct eth_hdr *ethhdr;
00087   struct pbuf *frame, *p;
00088   int len, read;
00089 
00090   while((len = pEth->receive()) != 0) {
00091       PacketsReceived++;
00092       frame = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
00093       if(frame == NULL) {
00094           return PacketsReceived;
00095       }
00096       p = frame;
00097       /* no packet could be read, silently ignore this */
00098       if (p == NULL) return PacketsReceived;
00099       do {
00100          read = pEth->read((char *)p->payload, p->len);
00101          p = p->next;
00102       } while(p != NULL && read != 0);
00103       
00104       /* Ignore this packet if it is too small to contain a valid Ethernet header. */
00105       if (len < (sizeof(struct eth_hdr) + ETH_PAD_SIZE))
00106       {
00107         pbuf_free(frame);
00108         frame = NULL;
00109         continue;
00110       }
00111       
00112       #if ETH_PAD_SIZE
00113           pbuf_header(p, ETH_PAD_SIZE);
00114       #endif
00115 
00116       ethhdr = (struct eth_hdr *)(frame->payload);
00117       
00118       switch (htons(ethhdr->type)) {
00119       /* IP or ARP packet? */
00120       case ETHTYPE_IP:
00121       case ETHTYPE_ARP:
00122       #if PPPOE_SUPPORT
00123       /* PPPoE packet? */
00124       case ETHTYPE_PPPOEDISC:
00125       case ETHTYPE_PPPOE:
00126       #endif /* PPPOE_SUPPORT */
00127       /* full packet send to tcpip_thread to process */
00128         //if (netif->input(p, gnetif)!=ERR_OK)
00129         if (ethernet_input(frame, eth_netif)!=ERR_OK)
00130         { LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
00131           pbuf_free(frame);
00132           frame = NULL;
00133         }
00134         break;
00135 
00136       default:
00137         pbuf_free(frame);
00138         frame = NULL;
00139         break;
00140       }
00141   }
00142 
00143   return PacketsReceived;
00144 }
00145 
00146 err_t eth_init(struct netif *netif) {
00147   LWIP_ASSERT("netif != NULL", (netif != NULL));
00148   
00149   NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 0x2EA);
00150   
00151   /* maximum transfer unit */
00152   netif->mtu = 0x2EA;
00153   
00154   /* device capabilities */
00155   /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
00156   netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_IGMP;
00157 
00158   netif->state = NULL;
00159   eth_netif = netif;
00160 
00161   netif->name[0] = IFNAME0;
00162   netif->name[1] = IFNAME1;
00163 
00164   /* We directly use etharp_output() here to save a function call.
00165    * You can instead declare your own function an call etharp_output()
00166    * from it if you have to do some checks before sending (e.g. if link
00167    * is available...) */
00168   netif->output          = etharp_output;
00169   netif->linkoutput      = eth_output;
00170 
00171   if (!pEth) pEth = new Ethernet(); // only create Ethernet object if required
00172 
00173   // UNDONE: Remove.  Just for debug
00174   pEth->set_link(Ethernet::HalfDuplex100);
00175   
00176   return ERR_OK;
00177 }
00178 
00179 void eth_free()
00180 {
00181   if(pEth)
00182     delete pEth;
00183   pEth = NULL;
00184 }
00185 
00186 void eth_address(char* mac) {
00187     pEth->address(mac);
00188 }
00189 
00190 Ethernet* eth_interface() {
00191     return pEth;
00192 }    
00193 
00194 #ifdef __cplusplus
00195 };
00196 #endif
00197 
00198 #endif