Web server based weather station using Sparkfun Weather Meters.
Dependencies: FatFileSystem mbed WeatherMeters SDFileSystem
network.cpp@1:c7958aa34fa1, 2012-02-25 (annotated)
- Committer:
- AdamGreen
- Date:
- Sat Feb 25 03:28:05 2012 +0000
- Revision:
- 1:c7958aa34fa1
- Parent:
- 0:616601bde9fb
Use published libraries where possible.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AdamGreen | 0:616601bde9fb | 1 | /* Copyright 2011 Adam Green (http://mbed.org/users/AdamGreen/) |
AdamGreen | 0:616601bde9fb | 2 | |
AdamGreen | 0:616601bde9fb | 3 | Licensed under the Apache License, Version 2.0 (the "License"); |
AdamGreen | 0:616601bde9fb | 4 | you may not use this file except in compliance with the License. |
AdamGreen | 0:616601bde9fb | 5 | You may obtain a copy of the License at |
AdamGreen | 0:616601bde9fb | 6 | |
AdamGreen | 0:616601bde9fb | 7 | http://www.apache.org/licenses/LICENSE-2.0 |
AdamGreen | 0:616601bde9fb | 8 | |
AdamGreen | 0:616601bde9fb | 9 | Unless required by applicable law or agreed to in writing, software |
AdamGreen | 0:616601bde9fb | 10 | distributed under the License is distributed on an "AS IS" BASIS, |
AdamGreen | 0:616601bde9fb | 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
AdamGreen | 0:616601bde9fb | 12 | See the License for the specific language governing permissions and |
AdamGreen | 0:616601bde9fb | 13 | limitations under the License. |
AdamGreen | 0:616601bde9fb | 14 | */ |
AdamGreen | 0:616601bde9fb | 15 | /* Implementation of core lwIP ethernet functionality. */ |
AdamGreen | 0:616601bde9fb | 16 | #include <mbed.h> |
AdamGreen | 0:616601bde9fb | 17 | #include "lwip/init.h" |
AdamGreen | 0:616601bde9fb | 18 | #include "lwip/tcp_impl.h" |
AdamGreen | 0:616601bde9fb | 19 | #include "lwip/dns.h" |
AdamGreen | 0:616601bde9fb | 20 | #include "netif/etharp.h" |
AdamGreen | 0:616601bde9fb | 21 | #include "drv/eth/eth_drv.h" |
AdamGreen | 0:616601bde9fb | 22 | #include "network.h" |
AdamGreen | 0:616601bde9fb | 23 | #include "debug.h" |
AdamGreen | 0:616601bde9fb | 24 | |
AdamGreen | 0:616601bde9fb | 25 | |
AdamGreen | 0:616601bde9fb | 26 | /* Initializes the network stack. |
AdamGreen | 0:616601bde9fb | 27 | |
AdamGreen | 0:616601bde9fb | 28 | NOTE: Using DHCP to supply the IP addresses is the only supported scenario |
AdamGreen | 0:616601bde9fb | 29 | in this sample. |
AdamGreen | 0:616601bde9fb | 30 | |
AdamGreen | 0:616601bde9fb | 31 | Parameters: |
AdamGreen | 0:616601bde9fb | 32 | pNetwork is a pointer to the network object to be initialized. |
AdamGreen | 0:616601bde9fb | 33 | pIPAddress is a pointer to the string which specifies the static IP address |
AdamGreen | 0:616601bde9fb | 34 | of this node. Set to NULL for DHCP. |
AdamGreen | 0:616601bde9fb | 35 | pSubnetMask is a pointer to the string which specifies the subnet mask for |
AdamGreen | 0:616601bde9fb | 36 | static IP addresses. Set to NULL for DHCP. |
AdamGreen | 0:616601bde9fb | 37 | pGatewayAddress is a pointer to the string which specifies the static |
AdamGreen | 0:616601bde9fb | 38 | gateway IP address. Set to NULL for DHCP. |
AdamGreen | 0:616601bde9fb | 39 | pHostName is the host name to be used for representing this device to the |
AdamGreen | 0:616601bde9fb | 40 | DHCP server. |
AdamGreen | 0:616601bde9fb | 41 | |
AdamGreen | 0:616601bde9fb | 42 | Returns: |
AdamGreen | 0:616601bde9fb | 43 | 0 on success and a positive error code otherwise. |
AdamGreen | 0:616601bde9fb | 44 | */ |
AdamGreen | 0:616601bde9fb | 45 | int SNetwork_Init(SNetwork* pNetwork, |
AdamGreen | 0:616601bde9fb | 46 | const char* pIPAddress, |
AdamGreen | 0:616601bde9fb | 47 | const char* pSubnetMask, |
AdamGreen | 0:616601bde9fb | 48 | const char* pGatewayAddress, |
AdamGreen | 0:616601bde9fb | 49 | const char* pHostName) |
AdamGreen | 0:616601bde9fb | 50 | { |
AdamGreen | 0:616601bde9fb | 51 | int Return = 1; |
AdamGreen | 0:616601bde9fb | 52 | netif* pAddResult = NULL; |
AdamGreen | 0:616601bde9fb | 53 | ip_addr_t IpAddress; |
AdamGreen | 0:616601bde9fb | 54 | ip_addr_t NetMask; |
AdamGreen | 0:616601bde9fb | 55 | ip_addr_t GatewayAddress; |
AdamGreen | 0:616601bde9fb | 56 | Timer Timeout; |
AdamGreen | 0:616601bde9fb | 57 | |
AdamGreen | 0:616601bde9fb | 58 | // Must specify a network object to be initialized. |
AdamGreen | 0:616601bde9fb | 59 | assert ( pNetwork ); |
AdamGreen | 0:616601bde9fb | 60 | |
AdamGreen | 0:616601bde9fb | 61 | // Clear out the network object and fill it in during the initialization |
AdamGreen | 0:616601bde9fb | 62 | // process. |
AdamGreen | 0:616601bde9fb | 63 | memset(pNetwork, 0, sizeof(*pNetwork)); |
AdamGreen | 0:616601bde9fb | 64 | |
AdamGreen | 0:616601bde9fb | 65 | // Initialize the lwIP network stack. |
AdamGreen | 0:616601bde9fb | 66 | lwip_init(); |
AdamGreen | 0:616601bde9fb | 67 | |
AdamGreen | 0:616601bde9fb | 68 | // Set the initial IP addresses for the ethernet interface based on whether |
AdamGreen | 0:616601bde9fb | 69 | // DHCP is to be used or not. |
AdamGreen | 0:616601bde9fb | 70 | if (pIPAddress) |
AdamGreen | 0:616601bde9fb | 71 | { |
AdamGreen | 0:616601bde9fb | 72 | // For static IP, all strings must be set. |
AdamGreen | 0:616601bde9fb | 73 | assert ( pSubnetMask && pGatewayAddress ); |
AdamGreen | 0:616601bde9fb | 74 | |
AdamGreen | 0:616601bde9fb | 75 | ip4_addr_set_u32(&IpAddress, ipaddr_addr(pIPAddress)); |
AdamGreen | 0:616601bde9fb | 76 | ip4_addr_set_u32(&NetMask, ipaddr_addr(pSubnetMask)); |
AdamGreen | 0:616601bde9fb | 77 | ip4_addr_set_u32(&GatewayAddress, ipaddr_addr(pGatewayAddress)); |
AdamGreen | 0:616601bde9fb | 78 | } |
AdamGreen | 0:616601bde9fb | 79 | else |
AdamGreen | 0:616601bde9fb | 80 | { |
AdamGreen | 0:616601bde9fb | 81 | // For DHCP, all strings must be NULL. |
AdamGreen | 0:616601bde9fb | 82 | assert ( !pSubnetMask && !pGatewayAddress ); |
AdamGreen | 0:616601bde9fb | 83 | |
AdamGreen | 0:616601bde9fb | 84 | // Clear the IP addresses and use DHCP instead. |
AdamGreen | 0:616601bde9fb | 85 | ip_addr_set_zero(&IpAddress); |
AdamGreen | 0:616601bde9fb | 86 | ip_addr_set_zero(&NetMask); |
AdamGreen | 0:616601bde9fb | 87 | ip_addr_set_zero(&GatewayAddress); |
AdamGreen | 0:616601bde9fb | 88 | } |
AdamGreen | 0:616601bde9fb | 89 | |
AdamGreen | 0:616601bde9fb | 90 | // Obtain the MAC address for the Ethernet device. |
AdamGreen | 0:616601bde9fb | 91 | // NOTE: This should really be done in eth_init() |
AdamGreen | 0:616601bde9fb | 92 | pNetwork->EthernetInterface.hwaddr_len = ETHARP_HWADDR_LEN; |
AdamGreen | 0:616601bde9fb | 93 | eth_address((char *)pNetwork->EthernetInterface.hwaddr); |
AdamGreen | 0:616601bde9fb | 94 | |
AdamGreen | 0:616601bde9fb | 95 | // Connect the LPC17xx ethernet driver into the lwIP stack. |
AdamGreen | 0:616601bde9fb | 96 | pAddResult = netif_add(&pNetwork->EthernetInterface, |
AdamGreen | 0:616601bde9fb | 97 | &IpAddress, |
AdamGreen | 0:616601bde9fb | 98 | &NetMask, |
AdamGreen | 0:616601bde9fb | 99 | &GatewayAddress, |
AdamGreen | 0:616601bde9fb | 100 | NULL, |
AdamGreen | 0:616601bde9fb | 101 | eth_init, |
AdamGreen | 0:616601bde9fb | 102 | ethernet_input); |
AdamGreen | 0:616601bde9fb | 103 | if (!pAddResult) |
AdamGreen | 0:616601bde9fb | 104 | { |
AdamGreen | 0:616601bde9fb | 105 | printf("error: Failed to add ethernet interface to lwIP.\r\n"); |
AdamGreen | 0:616601bde9fb | 106 | goto Error; |
AdamGreen | 0:616601bde9fb | 107 | } |
AdamGreen | 0:616601bde9fb | 108 | netif_set_default(&pNetwork->EthernetInterface); |
AdamGreen | 0:616601bde9fb | 109 | |
AdamGreen | 0:616601bde9fb | 110 | // Start the required timers. |
AdamGreen | 0:616601bde9fb | 111 | pNetwork->ARP.start(); |
AdamGreen | 0:616601bde9fb | 112 | pNetwork->DHCPCoarse.start(); |
AdamGreen | 0:616601bde9fb | 113 | pNetwork->DHCPFine.start(); |
AdamGreen | 0:616601bde9fb | 114 | pNetwork->TCP.start(); |
AdamGreen | 0:616601bde9fb | 115 | pNetwork->DNS.start(); |
AdamGreen | 0:616601bde9fb | 116 | |
AdamGreen | 0:616601bde9fb | 117 | if (pIPAddress) |
AdamGreen | 0:616601bde9fb | 118 | { |
AdamGreen | 0:616601bde9fb | 119 | // Start the ethernet interface up with the static IP address. |
AdamGreen | 0:616601bde9fb | 120 | netif_set_up(&pNetwork->EthernetInterface); |
AdamGreen | 0:616601bde9fb | 121 | } |
AdamGreen | 0:616601bde9fb | 122 | else |
AdamGreen | 0:616601bde9fb | 123 | { |
AdamGreen | 0:616601bde9fb | 124 | err_t StartResult; |
AdamGreen | 0:616601bde9fb | 125 | |
AdamGreen | 0:616601bde9fb | 126 | // Start the DHCP request. |
AdamGreen | 0:616601bde9fb | 127 | pNetwork->EthernetInterface.hostname = (char*)pHostName; |
AdamGreen | 0:616601bde9fb | 128 | dhcp_set_struct(&pNetwork->EthernetInterface, &pNetwork->DHCP); |
AdamGreen | 0:616601bde9fb | 129 | StartResult = dhcp_start(&pNetwork->EthernetInterface); |
AdamGreen | 0:616601bde9fb | 130 | if (ERR_OK != StartResult) |
AdamGreen | 0:616601bde9fb | 131 | { |
AdamGreen | 0:616601bde9fb | 132 | printf("error: Failed to start DHCP service.\r\n"); |
AdamGreen | 0:616601bde9fb | 133 | goto Error; |
AdamGreen | 0:616601bde9fb | 134 | } |
AdamGreen | 0:616601bde9fb | 135 | } |
AdamGreen | 0:616601bde9fb | 136 | |
AdamGreen | 0:616601bde9fb | 137 | // Wait for network to startup. |
AdamGreen | 0:616601bde9fb | 138 | Timeout.start(); |
AdamGreen | 0:616601bde9fb | 139 | printf("Waiting for network...\r\n"); |
AdamGreen | 0:616601bde9fb | 140 | |
AdamGreen | 0:616601bde9fb | 141 | // Wait until interface is up |
AdamGreen | 0:616601bde9fb | 142 | while (!netif_is_up(&pNetwork->EthernetInterface)) |
AdamGreen | 0:616601bde9fb | 143 | { |
AdamGreen | 0:616601bde9fb | 144 | SNetwork_Poll(pNetwork); |
AdamGreen | 0:616601bde9fb | 145 | |
AdamGreen | 0:616601bde9fb | 146 | // Stop program if we get a timeout on DHCP attempt. |
AdamGreen | 0:616601bde9fb | 147 | if (Timeout.read_ms() > 10000) |
AdamGreen | 0:616601bde9fb | 148 | { |
AdamGreen | 0:616601bde9fb | 149 | printf("error: Timeout while waiting for network to initialize.\r\n"); |
AdamGreen | 0:616601bde9fb | 150 | goto Error; |
AdamGreen | 0:616601bde9fb | 151 | } |
AdamGreen | 0:616601bde9fb | 152 | } |
AdamGreen | 0:616601bde9fb | 153 | |
AdamGreen | 0:616601bde9fb | 154 | // Print out the DHCP provided IP addresses. |
AdamGreen | 0:616601bde9fb | 155 | printf("IP : "); |
AdamGreen | 0:616601bde9fb | 156 | SNetwork_PrintAddress(&pNetwork->EthernetInterface.ip_addr); |
AdamGreen | 0:616601bde9fb | 157 | printf("\r\n"); |
AdamGreen | 0:616601bde9fb | 158 | |
AdamGreen | 0:616601bde9fb | 159 | printf("Gateway: "); |
AdamGreen | 0:616601bde9fb | 160 | SNetwork_PrintAddress(&pNetwork->EthernetInterface.gw); |
AdamGreen | 0:616601bde9fb | 161 | printf("\r\n"); |
AdamGreen | 0:616601bde9fb | 162 | |
AdamGreen | 0:616601bde9fb | 163 | printf("Mask : "); |
AdamGreen | 0:616601bde9fb | 164 | SNetwork_PrintAddress(&pNetwork->EthernetInterface.netmask); |
AdamGreen | 0:616601bde9fb | 165 | printf("\r\n"); |
AdamGreen | 0:616601bde9fb | 166 | |
AdamGreen | 0:616601bde9fb | 167 | Return = 0; |
AdamGreen | 0:616601bde9fb | 168 | Error: |
AdamGreen | 0:616601bde9fb | 169 | return Return; |
AdamGreen | 0:616601bde9fb | 170 | } |
AdamGreen | 0:616601bde9fb | 171 | |
AdamGreen | 0:616601bde9fb | 172 | |
AdamGreen | 0:616601bde9fb | 173 | /* Called from within the main application loop to perform network maintenance |
AdamGreen | 0:616601bde9fb | 174 | tasks at appropriate time intervals and execute the ethernet driver which |
AdamGreen | 0:616601bde9fb | 175 | will push new network packets into the lwIP stack. lwIP will then call into |
AdamGreen | 0:616601bde9fb | 176 | the callbacks which have been configured by this application. |
AdamGreen | 0:616601bde9fb | 177 | |
AdamGreen | 0:616601bde9fb | 178 | Parameters: |
AdamGreen | 0:616601bde9fb | 179 | pNetwork is a pointer to the intitialized network object. |
AdamGreen | 0:616601bde9fb | 180 | |
AdamGreen | 0:616601bde9fb | 181 | Returns: |
AdamGreen | 0:616601bde9fb | 182 | Number of network tasks run during this polling process. If 0 then no |
AdamGreen | 0:616601bde9fb | 183 | network related tasks were completed during this polling iteration. |
AdamGreen | 0:616601bde9fb | 184 | */ |
AdamGreen | 0:616601bde9fb | 185 | int SNetwork_Poll(SNetwork* pNetwork) |
AdamGreen | 0:616601bde9fb | 186 | { |
AdamGreen | 0:616601bde9fb | 187 | int TasksRun = 0; |
AdamGreen | 0:616601bde9fb | 188 | |
AdamGreen | 0:616601bde9fb | 189 | // Validate parameters. |
AdamGreen | 0:616601bde9fb | 190 | assert ( pNetwork ); |
AdamGreen | 0:616601bde9fb | 191 | |
AdamGreen | 0:616601bde9fb | 192 | // Execute timed maintenance tasks. |
AdamGreen | 0:616601bde9fb | 193 | if (pNetwork->DHCPFine.read_ms() >= DHCP_FINE_TIMER_MSECS) |
AdamGreen | 0:616601bde9fb | 194 | { |
AdamGreen | 0:616601bde9fb | 195 | pNetwork->DHCPFine.reset(); |
AdamGreen | 0:616601bde9fb | 196 | dhcp_fine_tmr(); |
AdamGreen | 0:616601bde9fb | 197 | TasksRun++; |
AdamGreen | 0:616601bde9fb | 198 | } |
AdamGreen | 0:616601bde9fb | 199 | if (pNetwork->DHCPCoarse.read() >= DHCP_COARSE_TIMER_SECS) |
AdamGreen | 0:616601bde9fb | 200 | { |
AdamGreen | 0:616601bde9fb | 201 | pNetwork->DHCPCoarse.reset(); |
AdamGreen | 0:616601bde9fb | 202 | dhcp_coarse_tmr(); |
AdamGreen | 0:616601bde9fb | 203 | TasksRun++; |
AdamGreen | 0:616601bde9fb | 204 | } |
AdamGreen | 0:616601bde9fb | 205 | if (pNetwork->ARP.read_ms() >= ARP_TMR_INTERVAL) |
AdamGreen | 0:616601bde9fb | 206 | { |
AdamGreen | 0:616601bde9fb | 207 | pNetwork->ARP.reset(); |
AdamGreen | 0:616601bde9fb | 208 | etharp_tmr(); |
AdamGreen | 0:616601bde9fb | 209 | TasksRun++; |
AdamGreen | 0:616601bde9fb | 210 | } |
AdamGreen | 0:616601bde9fb | 211 | if (pNetwork->TCP.read_ms() >= TCP_TMR_INTERVAL) |
AdamGreen | 0:616601bde9fb | 212 | { |
AdamGreen | 0:616601bde9fb | 213 | pNetwork->TCP.reset(); |
AdamGreen | 0:616601bde9fb | 214 | tcp_tmr(); |
AdamGreen | 0:616601bde9fb | 215 | TasksRun++; |
AdamGreen | 0:616601bde9fb | 216 | } |
AdamGreen | 0:616601bde9fb | 217 | if (pNetwork->DNS.read_ms() >= DNS_TMR_INTERVAL) |
AdamGreen | 0:616601bde9fb | 218 | { |
AdamGreen | 0:616601bde9fb | 219 | pNetwork->DNS.reset(); |
AdamGreen | 0:616601bde9fb | 220 | dns_tmr(); |
AdamGreen | 0:616601bde9fb | 221 | TasksRun++; |
AdamGreen | 0:616601bde9fb | 222 | } |
AdamGreen | 0:616601bde9fb | 223 | |
AdamGreen | 0:616601bde9fb | 224 | // Poll the ethernet driver to let it pull packets in and push new packets |
AdamGreen | 0:616601bde9fb | 225 | // into the lwIP network stack. |
AdamGreen | 0:616601bde9fb | 226 | TasksRun += eth_poll(); |
AdamGreen | 0:616601bde9fb | 227 | |
AdamGreen | 0:616601bde9fb | 228 | return TasksRun; |
AdamGreen | 0:616601bde9fb | 229 | } |
AdamGreen | 0:616601bde9fb | 230 | |
AdamGreen | 0:616601bde9fb | 231 | |
AdamGreen | 0:616601bde9fb | 232 | /* Prints out the caller supplied IP address. |
AdamGreen | 0:616601bde9fb | 233 | |
AdamGreen | 0:616601bde9fb | 234 | Parameters: |
AdamGreen | 0:616601bde9fb | 235 | pAddress is a pointer to the ip4 address to be displayed. |
AdamGreen | 0:616601bde9fb | 236 | |
AdamGreen | 0:616601bde9fb | 237 | Returns: |
AdamGreen | 0:616601bde9fb | 238 | Nothing. |
AdamGreen | 0:616601bde9fb | 239 | */ |
AdamGreen | 0:616601bde9fb | 240 | void SNetwork_PrintAddress(ip_addr_t* pAddress) |
AdamGreen | 0:616601bde9fb | 241 | { |
AdamGreen | 0:616601bde9fb | 242 | // Validate parameters. |
AdamGreen | 0:616601bde9fb | 243 | assert ( pAddress ); |
AdamGreen | 0:616601bde9fb | 244 | |
AdamGreen | 0:616601bde9fb | 245 | printf("%d.%d.%d.%d", |
AdamGreen | 0:616601bde9fb | 246 | ip4_addr1(pAddress), |
AdamGreen | 0:616601bde9fb | 247 | ip4_addr2(pAddress), |
AdamGreen | 0:616601bde9fb | 248 | ip4_addr3(pAddress), |
AdamGreen | 0:616601bde9fb | 249 | ip4_addr4(pAddress)); |
AdamGreen | 0:616601bde9fb | 250 | } |