Adam Green / Mbed 2 deprecated WeatherStation

Dependencies:   FatFileSystem mbed WeatherMeters SDFileSystem

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers network.cpp Source File

network.cpp

00001 /* Copyright 2011 Adam Green (http://mbed.org/users/AdamGreen/)
00002 
00003    Licensed under the Apache License, Version 2.0 (the "License");
00004    you may not use this file except in compliance with the License.
00005    You may obtain a copy of the License at
00006 
00007        http://www.apache.org/licenses/LICENSE-2.0
00008 
00009    Unless required by applicable law or agreed to in writing, software
00010    distributed under the License is distributed on an "AS IS" BASIS,
00011    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012    See the License for the specific language governing permissions and
00013    limitations under the License.
00014 */
00015 /* Implementation of core lwIP ethernet functionality. */
00016 #include <mbed.h>
00017 #include "lwip/init.h"
00018 #include "lwip/tcp_impl.h"
00019 #include "lwip/dns.h"
00020 #include "netif/etharp.h"
00021 #include "drv/eth/eth_drv.h"
00022 #include "network.h"
00023 #include "debug.h"
00024 
00025 
00026 /* Initializes the network stack.
00027 
00028    NOTE: Using DHCP to supply the IP addresses is the only supported scenario
00029          in this sample.
00030    
00031    Parameters:
00032     pNetwork is a pointer to the network object to be initialized.
00033     pIPAddress is a pointer to the string which specifies the static IP address
00034         of this node.  Set to NULL for DHCP.
00035     pSubnetMask is a pointer to the string which specifies the subnet mask for
00036         static IP addresses.  Set to NULL for DHCP.
00037     pGatewayAddress is a pointer to the string which specifies the static 
00038         gateway IP address.  Set to NULL for DHCP.
00039     pHostName is the host name to be used for representing this device to the
00040         DHCP server.
00041     
00042    Returns:
00043     0 on success and a positive error code otherwise.
00044 */
00045 int SNetwork_Init(SNetwork*   pNetwork,
00046                   const char* pIPAddress,
00047                   const char* pSubnetMask,
00048                   const char* pGatewayAddress,
00049                   const char* pHostName)
00050 {
00051     int         Return = 1;
00052     netif*      pAddResult = NULL;
00053     ip_addr_t   IpAddress;
00054     ip_addr_t   NetMask;
00055     ip_addr_t   GatewayAddress;
00056     Timer       Timeout;
00057 
00058     // Must specify a network object to be initialized.
00059     assert ( pNetwork );
00060     
00061     // Clear out the network object and fill it in during the initialization
00062     // process.
00063     memset(pNetwork, 0, sizeof(*pNetwork));
00064     
00065     // Initialize the lwIP network stack.
00066     lwip_init();
00067     
00068     // Set the initial IP addresses for the ethernet interface based on whether
00069     // DHCP is to be used or not.
00070     if (pIPAddress)
00071     {
00072         // For static IP, all strings must be set.
00073         assert ( pSubnetMask && pGatewayAddress );
00074         
00075         ip4_addr_set_u32(&IpAddress,      ipaddr_addr(pIPAddress));
00076         ip4_addr_set_u32(&NetMask,        ipaddr_addr(pSubnetMask));
00077         ip4_addr_set_u32(&GatewayAddress, ipaddr_addr(pGatewayAddress));
00078     }
00079     else
00080     {
00081         // For DHCP, all strings must be NULL.
00082         assert ( !pSubnetMask && !pGatewayAddress );
00083 
00084         // Clear the IP addresses and use DHCP instead.
00085         ip_addr_set_zero(&IpAddress);
00086         ip_addr_set_zero(&NetMask);
00087         ip_addr_set_zero(&GatewayAddress);
00088     }
00089     
00090     // Obtain the MAC address for the Ethernet device.
00091     // NOTE: This should really be done in eth_init()
00092     pNetwork->EthernetInterface.hwaddr_len = ETHARP_HWADDR_LEN;
00093     eth_address((char *)pNetwork->EthernetInterface.hwaddr);    
00094     
00095     // Connect the LPC17xx ethernet driver into the lwIP stack.
00096     pAddResult = netif_add(&pNetwork->EthernetInterface, 
00097                            &IpAddress, 
00098                            &NetMask, 
00099                            &GatewayAddress, 
00100                            NULL, 
00101                            eth_init, 
00102                            ethernet_input);
00103     if (!pAddResult)
00104     {
00105         printf("error: Failed to add ethernet interface to lwIP.\r\n");
00106         goto Error;
00107     }
00108     netif_set_default(&pNetwork->EthernetInterface);
00109     
00110     // Start the required timers.
00111     pNetwork->ARP.start();
00112     pNetwork->DHCPCoarse.start();
00113     pNetwork->DHCPFine.start();
00114     pNetwork->TCP.start();
00115     pNetwork->DNS.start();
00116 
00117     if (pIPAddress)
00118     {
00119         // Start the ethernet interface up with the static IP address.
00120         netif_set_up(&pNetwork->EthernetInterface);
00121     }
00122     else
00123     {
00124         err_t StartResult;
00125         
00126         // Start the DHCP request.
00127         pNetwork->EthernetInterface.hostname = (char*)pHostName;
00128         dhcp_set_struct(&pNetwork->EthernetInterface, &pNetwork->DHCP);
00129         StartResult = dhcp_start(&pNetwork->EthernetInterface);
00130         if (ERR_OK != StartResult)
00131         {
00132             printf("error: Failed to start DHCP service.\r\n");
00133             goto Error;
00134         }
00135     }
00136 
00137     // Wait for network to startup.
00138     Timeout.start();
00139     printf("Waiting for network...\r\n");
00140 
00141     // Wait until interface is up
00142     while (!netif_is_up(&pNetwork->EthernetInterface)) 
00143     {
00144         SNetwork_Poll(pNetwork);
00145 
00146         // Stop program if we get a timeout on DHCP attempt.
00147         if (Timeout.read_ms() > 10000) 
00148         {
00149             printf("error: Timeout while waiting for network to initialize.\r\n");
00150             goto Error;
00151         }
00152     }
00153 
00154     // Print out the DHCP provided IP addresses.
00155     printf("IP     : "); 
00156     SNetwork_PrintAddress(&pNetwork->EthernetInterface.ip_addr);
00157     printf("\r\n");
00158 
00159     printf("Gateway: "); 
00160     SNetwork_PrintAddress(&pNetwork->EthernetInterface.gw);
00161     printf("\r\n");
00162 
00163     printf("Mask   : "); 
00164     SNetwork_PrintAddress(&pNetwork->EthernetInterface.netmask);
00165     printf("\r\n");
00166     
00167     Return = 0;
00168 Error:
00169     return Return;
00170 }
00171 
00172 
00173 /* Called from within the main application loop to perform network maintenance
00174    tasks at appropriate time intervals and execute the ethernet driver which 
00175    will push new network packets into the lwIP stack.  lwIP will then call into
00176    the callbacks which have been configured by this application.
00177    
00178    Parameters:
00179     pNetwork is a pointer to the intitialized network object.
00180     
00181    Returns:
00182     Number of network tasks run during this polling process.  If 0 then no
00183         network related tasks were completed during this polling iteration.
00184 */
00185 int SNetwork_Poll(SNetwork* pNetwork)
00186 {
00187     int TasksRun = 0;
00188     
00189     // Validate parameters.
00190     assert ( pNetwork );
00191     
00192     // Execute timed maintenance tasks.
00193     if (pNetwork->DHCPFine.read_ms() >= DHCP_FINE_TIMER_MSECS)
00194     {
00195         pNetwork->DHCPFine.reset();
00196         dhcp_fine_tmr();
00197         TasksRun++;
00198     }
00199     if (pNetwork->DHCPCoarse.read() >= DHCP_COARSE_TIMER_SECS)
00200     {
00201         pNetwork->DHCPCoarse.reset();
00202         dhcp_coarse_tmr();
00203         TasksRun++;
00204     }
00205     if (pNetwork->ARP.read_ms() >= ARP_TMR_INTERVAL)
00206     {
00207         pNetwork->ARP.reset();
00208         etharp_tmr();
00209         TasksRun++;
00210     }
00211     if (pNetwork->TCP.read_ms() >= TCP_TMR_INTERVAL)
00212     {
00213         pNetwork->TCP.reset();
00214         tcp_tmr();
00215         TasksRun++;
00216     }
00217     if (pNetwork->DNS.read_ms() >= DNS_TMR_INTERVAL)
00218     {
00219         pNetwork->DNS.reset();
00220         dns_tmr();
00221         TasksRun++;
00222     }
00223 
00224     // Poll the ethernet driver to let it pull packets in and push new packets
00225     // into the lwIP network stack.
00226     TasksRun += eth_poll();
00227     
00228     return TasksRun;
00229 }
00230 
00231 
00232 /* Prints out the caller supplied IP address.
00233 
00234    Parameters:
00235     pAddress is a pointer to the ip4 address to be displayed.
00236     
00237    Returns:
00238     Nothing.
00239 */
00240 void SNetwork_PrintAddress(ip_addr_t* pAddress)
00241 {
00242     // Validate parameters.
00243     assert ( pAddress );
00244     
00245     printf("%d.%d.%d.%d", 
00246            ip4_addr1(pAddress),
00247            ip4_addr2(pAddress),
00248            ip4_addr3(pAddress),
00249            ip4_addr4(pAddress));
00250 }