Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
nic.c
00001 /** 00002 * @file nic.c 00003 * @brief Network interface controller abstraction layer 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneTCP Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00026 * @version 1.7.6 00027 **/ 00028 00029 //Switch to the appropriate trace level 00030 #define TRACE_LEVEL NIC_TRACE_LEVEL 00031 00032 //Dependencies 00033 #include "core/net.h" 00034 #include "core/nic.h" 00035 #include "core/socket.h" 00036 #include "core/raw_socket.h" 00037 #include "core/tcp_misc.h" 00038 #include "core/udp.h" 00039 #include "ipv4/ipv4.h" 00040 #include "ipv6/ipv6.h" 00041 #include "dns/dns_cache.h" 00042 #include "dns/dns_client.h" 00043 #include "mdns/mdns_client.h" 00044 #include "mdns/mdns_responder.h" 00045 #include "dns_sd/dns_sd.h" 00046 #include "mibs/mib2_module.h" 00047 #include "debug.h" 00048 00049 //Tick counter to handle periodic operations 00050 systime_t nicTickCounter; 00051 00052 00053 /** 00054 * @brief Network controller timer handler 00055 * 00056 * This routine is periodically called by the TCP/IP stack to 00057 * handle periodic operations such as polling the link state 00058 * 00059 * @param[in] interface Underlying network interface 00060 **/ 00061 00062 void nicTick(NetInterface *interface) 00063 { 00064 //Disable interrupts 00065 interface->nicDriver->disableIrq(interface); 00066 00067 //Handle periodic operations 00068 interface->nicDriver->tick(interface); 00069 00070 //Re-enable interrupts if necessary 00071 if(interface->configured) 00072 interface->nicDriver->enableIrq(interface); 00073 } 00074 00075 00076 /** 00077 * @brief Send a packet to the network controller 00078 * @param[in] interface Underlying network interface 00079 * @param[in] buffer Multi-part buffer containing the data to send 00080 * @param[in] offset Offset to the first data byte 00081 * @return Error code 00082 **/ 00083 00084 error_t nicSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset) 00085 { 00086 error_t error; 00087 bool_t status; 00088 00089 #if (TRACE_LEVEL >= TRACE_LEVEL_DEBUG) 00090 //Retrieve the length of the packet 00091 size_t length = netBufferGetLength(buffer) - offset; 00092 00093 //Debug message 00094 TRACE_DEBUG("Sending packet (%" PRIuSIZE " bytes)...\r\n", length); 00095 TRACE_DEBUG_NET_BUFFER(" ", buffer, offset, length); 00096 #endif 00097 00098 //Wait for the transmitter to be ready to send 00099 status = osWaitForEvent(&interface->nicTxEvent, NIC_MAX_BLOCKING_TIME); 00100 00101 //Check whether the specified event is in signaled state 00102 if(status) 00103 { 00104 //Disable interrupts 00105 interface->nicDriver->disableIrq(interface); 00106 00107 //Send Ethernet frame 00108 error = interface->nicDriver->sendPacket(interface, buffer, offset); 00109 00110 //Re-enable interrupts if necessary 00111 if(interface->configured) 00112 interface->nicDriver->enableIrq(interface); 00113 } 00114 else 00115 { 00116 //The transmitter is busy... 00117 return ERROR_TRANSMITTER_BUSY; 00118 } 00119 00120 //Return status code 00121 return error; 00122 } 00123 00124 00125 /** 00126 * @brief Configure multicast MAC address filtering 00127 * @param[in] interface Underlying network interface 00128 * @return Error code 00129 **/ 00130 00131 error_t nicSetMulticastFilter(NetInterface *interface) 00132 { 00133 error_t error; 00134 00135 //Disable interrupts 00136 interface->nicDriver->disableIrq(interface); 00137 00138 //Update MAC filter table 00139 error = interface->nicDriver->setMulticastFilter(interface); 00140 00141 //Re-enable interrupts if necessary 00142 if(interface->configured) 00143 interface->nicDriver->enableIrq(interface); 00144 00145 //Return status code 00146 return error; 00147 } 00148 00149 00150 /** 00151 * @brief Handle a packet received by the network controller 00152 * @param[in] interface Underlying network interface 00153 * @param[in] packet Incoming packet to process 00154 * @param[in] length Total packet length 00155 **/ 00156 00157 void nicProcessPacket(NetInterface *interface, void *packet, size_t length) 00158 { 00159 NicType type; 00160 00161 //Re-enable interrupts if necessary 00162 if(interface->configured) 00163 interface->nicDriver->enableIrq(interface); 00164 00165 //Debug message 00166 TRACE_DEBUG("Packet received (%" PRIuSIZE " bytes)...\r\n", length); 00167 TRACE_DEBUG_ARRAY(" ", packet, length); 00168 00169 //Retrieve network interface type 00170 type = interface->nicDriver->type; 00171 00172 //Ethernet interface? 00173 if(type == NIC_TYPE_ETHERNET) 00174 { 00175 #if (ETH_SUPPORT == ENABLED) 00176 //Process incoming Ethernet frame 00177 ethProcessFrame(interface, packet, length); 00178 #endif 00179 } 00180 //PPP interface? 00181 else if(type == NIC_TYPE_PPP) 00182 { 00183 #if (PPP_SUPPORT == ENABLED) 00184 //Process incoming PPP frame 00185 pppProcessFrame(interface, packet, length); 00186 #endif 00187 } 00188 //6LoWPAN interface? 00189 else if(type == NIC_TYPE_6LOWPAN) 00190 { 00191 #if (IPV6_SUPPORT == ENABLED) 00192 NetBuffer1 buffer; 00193 00194 //The incoming packet fits in a single chunk 00195 buffer.chunkCount = 1; 00196 buffer.maxChunkCount = 1; 00197 buffer.chunk[0].address = packet; 00198 buffer.chunk[0].length = length; 00199 buffer.chunk[0].size = 0; 00200 00201 //Process incoming IPv6 packet 00202 ipv6ProcessPacket(interface, (NetBuffer *) &buffer, 0); 00203 #endif 00204 } 00205 00206 //Disable interrupts 00207 interface->nicDriver->disableIrq(interface); 00208 } 00209 00210 00211 /** 00212 * @brief Process link state change event 00213 * @param[in] interface Underlying network interface 00214 **/ 00215 00216 void nicNotifyLinkChange(NetInterface *interface) 00217 { 00218 uint_t i; 00219 Socket *socket; 00220 00221 //Re-enable interrupts if necessary 00222 if(interface->configured) 00223 interface->nicDriver->enableIrq(interface); 00224 00225 //Check link state 00226 if(interface->linkState) 00227 { 00228 //Display link state 00229 TRACE_INFO("Link is up (%s)...\r\n", interface->name); 00230 00231 //Display link speed 00232 if(interface->linkSpeed == NIC_LINK_SPEED_1GBPS) 00233 { 00234 //1000BASE-T 00235 TRACE_INFO(" Link speed = 1000 Mbps\r\n"); 00236 } 00237 else if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS) 00238 { 00239 //100BASE-TX 00240 TRACE_INFO(" Link speed = 100 Mbps\r\n"); 00241 } 00242 else if(interface->linkSpeed == NIC_LINK_SPEED_10MBPS) 00243 { 00244 //10BASE-T 00245 TRACE_INFO(" Link speed = 10 Mbps\r\n"); 00246 } 00247 else if(interface->linkSpeed != NIC_LINK_SPEED_UNKNOWN) 00248 { 00249 //10BASE-T 00250 TRACE_INFO(" Link speed = %" PRIu32 " bps\r\n", interface->linkSpeed); 00251 } 00252 00253 //Display duplex mode 00254 if(interface->duplexMode == NIC_FULL_DUPLEX_MODE) 00255 { 00256 //1000BASE-T 00257 TRACE_INFO(" Duplex mode = Full-Duplex\r\n"); 00258 } 00259 else if(interface->duplexMode == NIC_HALF_DUPLEX_MODE) 00260 { 00261 //100BASE-TX 00262 TRACE_INFO(" Duplex mode = Half-Duplex\r\n"); 00263 } 00264 } 00265 else 00266 { 00267 //Display link state 00268 TRACE_INFO("Link is down (%s)...\r\n", interface->name); 00269 } 00270 00271 //Interface's current bandwidth 00272 MIB2_SET_GAUGE32(interface->mibIfEntry->ifSpeed, interface->linkSpeed); 00273 00274 //The current operational state of the interface 00275 if(interface->linkState) 00276 MIB2_SET_INTEGER(interface->mibIfEntry->ifOperStatus, MIB2_IF_OPER_STATUS_UP); 00277 else 00278 MIB2_SET_INTEGER(interface->mibIfEntry->ifOperStatus, MIB2_IF_OPER_STATUS_DOWN); 00279 00280 //The time at which the interface entered its current operational state 00281 MIB2_SET_TIME_TICKS(interface->mibIfEntry->ifLastChange, osGetSystemTime() / 10); 00282 00283 #if (IPV4_SUPPORT == ENABLED) 00284 //Notify IPv4 of link state changes 00285 ipv4LinkChangeEvent(interface); 00286 #endif 00287 00288 #if (IPV6_SUPPORT == ENABLED) 00289 //Notify IPv6 of link state changes 00290 ipv6LinkChangeEvent(interface); 00291 #endif 00292 00293 #if (DNS_CLIENT_SUPPORT == ENABLED || MDNS_CLIENT_SUPPORT == ENABLED || \ 00294 NBNS_CLIENT_SUPPORT == ENABLED) 00295 //Flush DNS cache 00296 dnsFlushCache(interface); 00297 #endif 00298 00299 #if (MDNS_RESPONDER_SUPPORT == ENABLED) 00300 //Perform probing and announcing 00301 mdnsResponderLinkChangeEvent(interface->mdnsResponderContext); 00302 #endif 00303 00304 #if (DNS_SD_SUPPORT == ENABLED) 00305 //Perform probing and announcing 00306 dnsSdLinkChangeEvent(interface->dnsSdContext); 00307 #endif 00308 00309 //Notify registered users of link state changes 00310 netInvokeLinkChangeCallback(interface, interface->linkState); 00311 00312 //Loop through opened sockets 00313 for(i = 0; i < SOCKET_MAX_COUNT; i++) 00314 { 00315 //Point to the current socket 00316 socket = socketTable + i; 00317 00318 #if (TCP_SUPPORT == ENABLED) 00319 //Connection-oriented socket? 00320 if(socket->type == SOCKET_TYPE_STREAM) 00321 { 00322 tcpUpdateEvents(socket); 00323 } 00324 #endif 00325 #if (UDP_SUPPORT == ENABLED) 00326 //Connectionless socket? 00327 if(socket->type == SOCKET_TYPE_DGRAM) 00328 { 00329 udpUpdateEvents(socket); 00330 } 00331 #endif 00332 #if (RAW_SOCKET_SUPPORT == ENABLED) 00333 //Raw socket? 00334 if(socket->type == SOCKET_TYPE_RAW_IP || 00335 socket->type == SOCKET_TYPE_RAW_ETH) 00336 { 00337 rawSocketUpdateEvents(socket); 00338 } 00339 #endif 00340 } 00341 00342 //Disable interrupts 00343 interface->nicDriver->disableIrq(interface); 00344 } 00345
Generated on Tue Jul 12 2022 17:10:15 by
 1.7.2