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.
net.c
00001 /** 00002 * @file net.c 00003 * @brief TCP/IP stack core 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 ETH_TRACE_LEVEL 00031 00032 //Dependencies 00033 #include <stdlib.h> 00034 #include "core/net.h" 00035 #include "core/socket.h" 00036 #include "core/tcp_timer.h" 00037 #include "core/ethernet.h" 00038 #include "ipv4/arp.h" 00039 #include "ipv4/ipv4.h" 00040 #include "ipv4/ipv4_routing.h" 00041 #include "ipv4/igmp.h" 00042 #include "ipv6/ipv6.h" 00043 #include "ipv6/ipv6_routing.h" 00044 #include "ipv6/mld.h" 00045 #include "ipv6/ndp.h" 00046 #include "ipv6/ndp_router_adv.h" 00047 #include "dhcp/dhcp_client.h" 00048 #include "dhcp/dhcp_server.h" 00049 #include "dns/dns_cache.h" 00050 #include "dns/dns_client.h" 00051 #include "mdns/mdns_client.h" 00052 #include "mdns/mdns_responder.h" 00053 #include "mdns/mdns_common.h" 00054 #include "dns_sd/dns_sd.h" 00055 #include "netbios/nbns_client.h" 00056 #include "netbios/nbns_responder.h" 00057 #include "netbios/nbns_common.h" 00058 #include "dns_sd/dns_sd.h" 00059 #include "mibs/mib2_module.h" 00060 #include "str.h" 00061 #include "debug.h" 00062 00063 #if (WEB_SOCKET_SUPPORT == ENABLED) 00064 #include "web_socket/web_socket.h" 00065 #endif 00066 00067 //TCP/IP stack handle 00068 OsTask *netTaskHandle; 00069 //Mutex preventing simultaneous access to the TCP/IP stack 00070 OsMutex netMutex; 00071 //Event object to receive notifications from device drivers 00072 OsEvent netEvent; 00073 //Network interfaces 00074 NetInterface netInterface[NET_INTERFACE_COUNT]; 00075 00076 //TCP/IP process state 00077 static bool_t netTaskRunning; 00078 //Timestamp 00079 static systime_t netTimestamp; 00080 //Pseudo-random number generator state 00081 static uint32_t prngState = 0; 00082 00083 //Mutex to prevent simultaneous access to the callback table 00084 static OsMutex callbackTableMutex; 00085 //Table that holds the registered user callbacks 00086 static LinkChangeCallbackDesc callbackTable[NET_CALLBACK_TABLE_SIZE]; 00087 00088 //Check TCP/IP stack configuration 00089 #if (NET_STATIC_OS_RESOURCES == ENABLED) 00090 00091 //Task responsible for handling TCP/IP events 00092 static OsTask netTaskInstance; 00093 static uint_t netTaskStack[NET_TASK_STACK_SIZE]; 00094 00095 #endif 00096 00097 00098 /** 00099 * @brief TCP/IP stack initialization 00100 * @return Error code 00101 **/ 00102 00103 error_t netInit(void) 00104 { 00105 error_t error; 00106 uint_t i; 00107 NetInterface *interface; 00108 00109 //The TCP/IP process is currently suspended 00110 netTaskRunning = FALSE; 00111 //Get current time 00112 netTimestamp = osGetSystemTime(); 00113 00114 //Create a mutex to prevent simultaneous access to the TCP/IP stack 00115 if(!osCreateMutex(&netMutex)) 00116 { 00117 //Failed to create mutex 00118 return ERROR_OUT_OF_RESOURCES; 00119 } 00120 00121 //Create a event object to receive notifications from device drivers 00122 if(!osCreateEvent(&netEvent)) 00123 { 00124 //Failed to create mutex 00125 return ERROR_OUT_OF_RESOURCES; 00126 } 00127 00128 //Memory pool initialization 00129 error = memPoolInit(); 00130 //Any error to report? 00131 if(error) 00132 return error; 00133 00134 //Clear configuration data for each interface 00135 memset(netInterface, 0, sizeof(netInterface)); 00136 00137 //Save the number of interfaces 00138 MIB2_SET_INTEGER(mib2Base.ifGroup.ifNumber, NET_INTERFACE_COUNT); 00139 00140 //Loop through network interfaces 00141 for(i = 0; i < NET_INTERFACE_COUNT; i++) 00142 { 00143 //Point to the current interface 00144 interface = &netInterface[i]; 00145 00146 //Default interface name 00147 sprintf(interface->name, "eth%u", i); 00148 //Default interface identifier 00149 interface->id = i; 00150 //Default PHY address 00151 interface->phyAddr = UINT8_MAX; 00152 00153 #if (MIB2_SUPPORT == ENABLED) 00154 //MIB ifEntry object 00155 interface->mibIfEntry = &mib2Base.ifGroup.ifTable[i]; 00156 #endif 00157 00158 //Interface identifier 00159 MIB2_SET_INTEGER(interface->mibIfEntry->ifIndex, i + 1); 00160 //Interface name 00161 MIB2_SET_OCTET_STRING(interface->mibIfEntry->ifDescr, interface->name, strlen(interface->name)); 00162 MIB2_SET_OCTET_STRING_LEN(interface->mibIfEntry->ifDescrLen, strlen(interface->name)); 00163 //Default interface type 00164 MIB2_SET_INTEGER(interface->mibIfEntry->ifType, MIB2_IF_TYPE_OTHER); 00165 //Default interface state 00166 MIB2_SET_INTEGER(interface->mibIfEntry->ifAdminStatus, MIB2_IF_ADMIN_STATUS_DOWN); 00167 MIB2_SET_INTEGER(interface->mibIfEntry->ifOperStatus, MIB2_IF_OPER_STATUS_DOWN); 00168 } 00169 00170 //Create a mutex to prevent simultaneous access to the callback table 00171 if(!osCreateMutex(&callbackTableMutex)) 00172 { 00173 //Failed to create mutex 00174 return ERROR_OUT_OF_RESOURCES; 00175 } 00176 00177 //Initialize callback table 00178 memset(callbackTable, 0, sizeof(callbackTable)); 00179 00180 //Socket related initialization 00181 error = socketInit(); 00182 //Any error to report? 00183 if(error) 00184 return error; 00185 00186 #if (WEB_SOCKET_SUPPORT == ENABLED) 00187 //WebSocket related initialization 00188 webSocketInit(); 00189 #endif 00190 00191 #if (IPV4_SUPPORT == ENABLED && IPV4_ROUTING_SUPPORT == ENABLED) 00192 //Initialize IPv4 routing table 00193 error = ipv4InitRouting(); 00194 //Any error to report? 00195 if(error) 00196 return error; 00197 #endif 00198 00199 #if (IPV6_SUPPORT == ENABLED && IPV6_ROUTING_SUPPORT == ENABLED) 00200 //Initialize IPv6 routing table 00201 error = ipv6InitRouting(); 00202 //Any error to report? 00203 if(error) 00204 return error; 00205 #endif 00206 00207 #if (UDP_SUPPORT == ENABLED) 00208 //UDP related initialization 00209 error = udpInit(); 00210 //Any error to report? 00211 if(error) 00212 return error; 00213 #endif 00214 00215 #if (TCP_SUPPORT == ENABLED) 00216 //TCP related initialization 00217 error = tcpInit(); 00218 //Any error to report? 00219 if(error) 00220 return error; 00221 #endif 00222 00223 #if (DNS_CLIENT_SUPPORT == ENABLED || MDNS_CLIENT_SUPPORT == ENABLED || \ 00224 NBNS_CLIENT_SUPPORT == ENABLED) 00225 //DNS cache initialization 00226 error = dnsInit(); 00227 //Any error to report? 00228 if(error) 00229 return error; 00230 #endif 00231 00232 //Initialize tick counters 00233 nicTickCounter = 0; 00234 00235 #if (PPP_SUPPORT == ENABLED) 00236 pppTickCounter = 0; 00237 #endif 00238 #if (IPV4_SUPPORT == ENABLED && ETH_SUPPORT == ENABLED) 00239 arpTickCounter = 0; 00240 #endif 00241 #if (IPV4_SUPPORT == ENABLED && IPV4_FRAG_SUPPORT == ENABLED) 00242 ipv4FragTickCounter = 0; 00243 #endif 00244 #if (IPV4_SUPPORT == ENABLED && IGMP_SUPPORT == ENABLED) 00245 igmpTickCounter = 0; 00246 #endif 00247 #if (IPV4_SUPPORT == ENABLED && AUTO_IP_SUPPORT == ENABLED) 00248 autoIpTickCounter = 0; 00249 #endif 00250 #if (IPV4_SUPPORT == ENABLED && DHCP_CLIENT_SUPPORT == ENABLED) 00251 dhcpClientTickCounter = 0; 00252 #endif 00253 #if (IPV4_SUPPORT == ENABLED && DHCP_SERVER_SUPPORT == ENABLED) 00254 dhcpServerTickCounter = 0; 00255 #endif 00256 #if (IPV6_SUPPORT == ENABLED && IPV6_FRAG_SUPPORT == ENABLED) 00257 ipv6FragTickCounter = 0; 00258 #endif 00259 #if (IPV6_SUPPORT == ENABLED && MLD_SUPPORT == ENABLED) 00260 mldTickCounter = 0; 00261 #endif 00262 #if (IPV6_SUPPORT == ENABLED && NDP_SUPPORT == ENABLED) 00263 ndpTickCounter = 0; 00264 #endif 00265 #if (IPV6_SUPPORT == ENABLED && NDP_ROUTER_ADV_SUPPORT == ENABLED) 00266 ndpRouterAdvTickCounter = 0; 00267 #endif 00268 #if (IPV6_SUPPORT == ENABLED && DHCPV6_CLIENT_SUPPORT == ENABLED) 00269 dhcpv6ClientTickCounter = 0; 00270 #endif 00271 #if (TCP_SUPPORT == ENABLED) 00272 tcpTickCounter = 0; 00273 #endif 00274 #if (DNS_CLIENT_SUPPORT == ENABLED || MDNS_CLIENT_SUPPORT == ENABLED || \ 00275 NBNS_CLIENT_SUPPORT == ENABLED) 00276 dnsTickCounter = 0; 00277 #endif 00278 #if (MDNS_RESPONDER_SUPPORT == ENABLED) 00279 mdnsResponderTickCounter = 0; 00280 #endif 00281 #if (DNS_SD_SUPPORT == ENABLED) 00282 dnsSdTickCounter = 0; 00283 #endif 00284 00285 #if (NET_STATIC_OS_RESOURCES == ENABLED) 00286 //Create a task to handle TCP/IP events 00287 osCreateStaticTask(&netTaskInstance, "TCP/IP Stack", (OsTaskCode) netTask, 00288 NULL, netTaskStack, NET_TASK_STACK_SIZE, NET_TASK_PRIORITY); 00289 #else 00290 //Create a task to handle TCP/IP events 00291 netTaskHandle = osCreateTask("TCP/IP Stack", (OsTaskCode) netTask, 00292 NULL, NET_TASK_STACK_SIZE, NET_TASK_PRIORITY); 00293 00294 //Unable to create the task? 00295 if(netTaskHandle == OS_INVALID_HANDLE) 00296 return ERROR_OUT_OF_RESOURCES; 00297 #endif 00298 00299 #if (NET_RTOS_SUPPORT == DISABLED) 00300 //The TCP/IP process is now running 00301 netTaskRunning = TRUE; 00302 #endif 00303 00304 //Successful initialization 00305 return NO_ERROR; 00306 } 00307 00308 00309 /** 00310 * @brief Set MAC address 00311 * @param[in] interface Pointer to the desired network interface 00312 * @param[in] macAddr MAC address 00313 * @return Error code 00314 **/ 00315 00316 error_t netSetMacAddr(NetInterface *interface, const MacAddr *macAddr) 00317 { 00318 //Check parameters 00319 if(interface == NULL || macAddr == NULL) 00320 return ERROR_INVALID_PARAMETER; 00321 00322 #if (ETH_SUPPORT == ENABLED) 00323 //Get exclusive access 00324 osAcquireMutex(&netMutex); 00325 00326 //Set MAC address 00327 interface->macAddr = *macAddr; 00328 00329 //Generate the 64-bit interface identifier 00330 macAddrToEui64(macAddr, &interface->eui64); 00331 00332 //Interface's physical address 00333 MIB2_SET_OCTET_STRING(interface->mibIfEntry->ifPhysAddress, &interface->macAddr, 6); 00334 MIB2_SET_OCTET_STRING_LEN(interface->mibIfEntry->ifPhysAddressLen, 6); 00335 00336 //Release exclusive access 00337 osReleaseMutex(&netMutex); 00338 #endif 00339 00340 //Successful processing 00341 return NO_ERROR; 00342 } 00343 00344 00345 /** 00346 * @brief Retrieve MAC address 00347 * @param[in] interface Pointer to the desired network interface 00348 * @param[out] macAddr MAC address 00349 * @return Error code 00350 **/ 00351 00352 error_t netGetMacAddr(NetInterface *interface, MacAddr *macAddr) 00353 { 00354 //Check parameters 00355 if(interface == NULL || macAddr == NULL) 00356 return ERROR_INVALID_PARAMETER; 00357 00358 #if (ETH_SUPPORT == ENABLED) 00359 //Get exclusive access 00360 osAcquireMutex(&netMutex); 00361 //Get MAC address 00362 *macAddr = interface->macAddr; 00363 //Release exclusive access 00364 osReleaseMutex(&netMutex); 00365 #endif 00366 00367 //Successful processing 00368 return NO_ERROR; 00369 } 00370 00371 00372 /** 00373 * @brief Set EUI-64 interface identifier 00374 * @param[in] interface Pointer to the desired network interface 00375 * @param[in] eui64 Interface identifier 00376 * @return Error code 00377 **/ 00378 00379 error_t netSetEui64(NetInterface *interface, const Eui64 *eui64) 00380 { 00381 //Check parameters 00382 if(interface == NULL || eui64 == NULL) 00383 return ERROR_INVALID_PARAMETER; 00384 00385 //Get exclusive access 00386 osAcquireMutex(&netMutex); 00387 //Set interface identifier 00388 interface->eui64 = *eui64; 00389 //Release exclusive access 00390 osReleaseMutex(&netMutex); 00391 00392 //Successful processing 00393 return NO_ERROR; 00394 } 00395 00396 00397 /** 00398 * @brief Retrieve EUI-64 interface identifier 00399 * @param[in] interface Pointer to the desired network interface 00400 * @param[out] eui64 Interface identifier 00401 * @return Error code 00402 **/ 00403 00404 error_t netGetEui64(NetInterface *interface, Eui64 *eui64) 00405 { 00406 //Check parameters 00407 if(interface == NULL || eui64 == NULL) 00408 return ERROR_INVALID_PARAMETER; 00409 00410 //Get exclusive access 00411 osAcquireMutex(&netMutex); 00412 //Get interface identifier 00413 *eui64 = interface->eui64; 00414 //Release exclusive access 00415 osReleaseMutex(&netMutex); 00416 00417 //Successful processing 00418 return NO_ERROR; 00419 } 00420 00421 00422 /** 00423 * @brief Set interface identifier 00424 * @param[in] interface Pointer to the desired network interface 00425 * @param[in] id Unique number identifying the interface 00426 * @return Error code 00427 **/ 00428 00429 error_t netSetInterfaceId(NetInterface *interface, uint32_t id) 00430 { 00431 //Check parameters 00432 if(interface == NULL) 00433 return ERROR_INVALID_PARAMETER; 00434 00435 //Get exclusive access 00436 osAcquireMutex(&netMutex); 00437 //Set interface identifier 00438 interface->id = id; 00439 //Release exclusive access 00440 osReleaseMutex(&netMutex); 00441 00442 //Successful processing 00443 return NO_ERROR; 00444 } 00445 00446 00447 /** 00448 * @brief Set interface name 00449 * @param[in] interface Pointer to the desired network interface 00450 * @param[in] name NULL-terminated string that contains the interface name 00451 * @return Error code 00452 **/ 00453 00454 error_t netSetInterfaceName(NetInterface *interface, const char_t *name) 00455 { 00456 #if (MIB2_SUPPORT == ENABLED) 00457 size_t n; 00458 #endif 00459 00460 //Check parameters 00461 if(interface == NULL || name == NULL) 00462 return ERROR_INVALID_PARAMETER; 00463 00464 //Get exclusive access 00465 osAcquireMutex(&netMutex); 00466 00467 //Set interface name 00468 strSafeCopy(interface->name, name, NET_MAX_IF_NAME_LEN); 00469 00470 #if (MIB2_SUPPORT == ENABLED) 00471 //Get the length of the string 00472 n = strlen(interface->name); 00473 00474 //Text string containing information about the interface 00475 MIB2_SET_OCTET_STRING(interface->mibIfEntry->ifDescr, interface->name, n); 00476 MIB2_SET_OCTET_STRING_LEN(interface->mibIfEntry->ifDescrLen, n); 00477 #endif 00478 00479 //Release exclusive access 00480 osReleaseMutex(&netMutex); 00481 00482 //Successful processing 00483 return NO_ERROR; 00484 } 00485 00486 00487 /** 00488 * @brief Set host name 00489 * @param[in] interface Pointer to the desired network interface 00490 * @param[in] name NULL-terminated string that contains the host name 00491 * @return Error code 00492 **/ 00493 00494 error_t netSetHostname(NetInterface *interface, const char_t *name) 00495 { 00496 //Check parameters 00497 if(interface == NULL || name == NULL) 00498 return ERROR_INVALID_PARAMETER; 00499 00500 //Get exclusive access 00501 osAcquireMutex(&netMutex); 00502 00503 //Set host name 00504 strSafeCopy(interface->hostname, name, NET_MAX_HOSTNAME_LEN); 00505 00506 //Release exclusive access 00507 osReleaseMutex(&netMutex); 00508 00509 //Successful processing 00510 return NO_ERROR; 00511 } 00512 00513 00514 /** 00515 * @brief Set proxy server 00516 * @param[in] interface Pointer to the desired network interface 00517 * @param[in] name Proxy server name 00518 * @param[in] port Proxy server port 00519 * @return Error code 00520 **/ 00521 00522 error_t netSetProxy(NetInterface *interface, const char_t *name, uint16_t port) 00523 { 00524 //Check parameters 00525 if(interface == NULL || name == NULL) 00526 return ERROR_INVALID_PARAMETER; 00527 00528 //Get exclusive access 00529 osAcquireMutex(&netMutex); 00530 00531 //Set proxy server name 00532 strSafeCopy(interface->proxyName, name, NET_MAX_PROXY_NAME_LEN); 00533 //Set proxy server port 00534 interface->proxyPort = port; 00535 00536 //Release exclusive access 00537 osReleaseMutex(&netMutex); 00538 00539 //Successful processing 00540 return NO_ERROR; 00541 } 00542 00543 00544 /** 00545 * @brief Set Ethernet MAC driver 00546 * @param[in] interface Pointer to the desired network interface 00547 * @param[in] driver Ethernet MAC driver 00548 * @return Error code 00549 **/ 00550 00551 error_t netSetDriver(NetInterface *interface, const NicDriver *driver) 00552 { 00553 //Check parameters 00554 if(interface == NULL || driver == NULL) 00555 return ERROR_INVALID_PARAMETER; 00556 00557 //Get exclusive access 00558 osAcquireMutex(&netMutex); 00559 00560 //Set Ethernet MAC driver 00561 interface->nicDriver = driver; 00562 00563 //Set interface type 00564 if(driver->type == NIC_TYPE_ETHERNET) 00565 { 00566 //Ethernet interface 00567 MIB2_SET_INTEGER(interface->mibIfEntry->ifType, MIB2_IF_TYPE_ETHERNET_CSMACD); 00568 } 00569 else if(driver->type == NIC_TYPE_PPP) 00570 { 00571 //PPP interface 00572 MIB2_SET_INTEGER(interface->mibIfEntry->ifType, MIB2_IF_TYPE_PPP); 00573 } 00574 else if(driver->type == NIC_TYPE_6LOWPAN) 00575 { 00576 //IEEE 802.15.4 WPAN interface 00577 MIB2_SET_INTEGER(interface->mibIfEntry->ifType, MIB2_IF_TYPE_IEEE_802_15_4); 00578 } 00579 else 00580 { 00581 //Unknown interface type 00582 MIB2_SET_INTEGER(interface->mibIfEntry->ifType, MIB2_IF_TYPE_OTHER); 00583 } 00584 00585 //Set interface MTU 00586 MIB2_SET_INTEGER(interface->mibIfEntry->ifMtu, driver->mtu); 00587 //Update interface state 00588 MIB2_SET_INTEGER(interface->mibIfEntry->ifAdminStatus, MIB2_IF_ADMIN_STATUS_UP); 00589 00590 //Release exclusive access 00591 osReleaseMutex(&netMutex); 00592 00593 //Successful processing 00594 return NO_ERROR; 00595 } 00596 00597 00598 /** 00599 * @brief Set Ethernet PHY driver 00600 * @param[in] interface Pointer to the desired network interface 00601 * @param[in] driver Ethernet PHY driver (can be NULL for MAC + PHY controller) 00602 * @return Error code 00603 **/ 00604 00605 error_t netSetPhyDriver(NetInterface *interface, const PhyDriver *driver) 00606 { 00607 //Check parameters 00608 if(interface == NULL || driver == NULL) 00609 return ERROR_INVALID_PARAMETER; 00610 00611 //Get exclusive access 00612 osAcquireMutex(&netMutex); 00613 //Set Ethernet PHY driver 00614 interface->phyDriver = driver; 00615 //Release exclusive access 00616 osReleaseMutex(&netMutex); 00617 00618 //Successful processing 00619 return NO_ERROR; 00620 } 00621 00622 00623 /** 00624 * @brief Set Ethernet PHY address 00625 * @param[in] interface Pointer to the desired network interface 00626 * @param[in] phyAddr PHY address 00627 * @return Error code 00628 **/ 00629 00630 error_t netSetPhyAddr(NetInterface *interface, uint8_t phyAddr) 00631 { 00632 //Make sure the network interface is valid 00633 if(interface == NULL) 00634 return ERROR_INVALID_PARAMETER; 00635 00636 //Make sure the PHY address is valid 00637 if(phyAddr >= 32) 00638 return ERROR_OUT_OF_RANGE; 00639 00640 //Get exclusive access 00641 osAcquireMutex(&netMutex); 00642 //Set PHY address 00643 interface->phyAddr = phyAddr; 00644 //Release exclusive access 00645 osReleaseMutex(&netMutex); 00646 00647 //Successful processing 00648 return NO_ERROR; 00649 } 00650 00651 00652 /** 00653 * @brief Set SPI driver 00654 * @param[in] interface Pointer to the desired network interface 00655 * @param[in] driver Underlying SPI driver 00656 * @return Error code 00657 **/ 00658 00659 error_t netSetSpiDriver(NetInterface *interface, const SpiDriver *driver) 00660 { 00661 //Check parameters 00662 if(interface == NULL || driver == NULL) 00663 return ERROR_INVALID_PARAMETER; 00664 00665 //Get exclusive access 00666 osAcquireMutex(&netMutex); 00667 //Set SPI driver 00668 interface->spiDriver = driver; 00669 //Release exclusive access 00670 osReleaseMutex(&netMutex); 00671 00672 //Successful processing 00673 return NO_ERROR; 00674 } 00675 00676 00677 /** 00678 * @brief Set UART driver 00679 * @param[in] interface Pointer to the desired network interface 00680 * @param[in] driver Underlying UART driver 00681 * @return Error code 00682 **/ 00683 00684 error_t netSetUartDriver(NetInterface *interface, const UartDriver *driver) 00685 { 00686 //Check parameters 00687 if(interface == NULL || driver == NULL) 00688 return ERROR_INVALID_PARAMETER; 00689 00690 //Get exclusive access 00691 osAcquireMutex(&netMutex); 00692 //Set UART driver 00693 interface->uartDriver = driver; 00694 //Release exclusive access 00695 osReleaseMutex(&netMutex); 00696 00697 //Successful processing 00698 return NO_ERROR; 00699 } 00700 00701 00702 /** 00703 * @brief Set external interrupt line driver 00704 * @param[in] interface Pointer to the desired network interface 00705 * @param[in] driver Underlying SPI driver 00706 * @return Error code 00707 **/ 00708 00709 error_t netSetExtIntDriver(NetInterface *interface, const ExtIntDriver *driver) 00710 { 00711 //Check parameters 00712 if(interface == NULL || driver == NULL) 00713 return ERROR_INVALID_PARAMETER; 00714 00715 //Get exclusive access 00716 osAcquireMutex(&netMutex); 00717 //Set external interrupt line driver 00718 interface->extIntDriver = driver; 00719 //Release exclusive access 00720 osReleaseMutex(&netMutex); 00721 00722 //Successful processing 00723 return NO_ERROR; 00724 } 00725 00726 00727 /** 00728 * @brief Set link state (for virtual drivers only) 00729 * @param[in] interface Pointer to the desired network interface 00730 * @param[in] linkState Link state 00731 * @return Error code 00732 **/ 00733 00734 error_t netSetLinkState(NetInterface *interface, NicLinkState linkState) 00735 { 00736 //Make sure the network interface is valid 00737 if(interface == NULL) 00738 return ERROR_INVALID_PARAMETER; 00739 00740 //Get exclusive access 00741 osAcquireMutex(&netMutex); 00742 00743 //Link state changed? 00744 if(linkState != interface->linkState) 00745 { 00746 //Update link state 00747 interface->linkState = linkState; 00748 //Process link state change event 00749 nicNotifyLinkChange(interface); 00750 } 00751 00752 //Release exclusive access 00753 osReleaseMutex(&netMutex); 00754 00755 //Successful processing 00756 return NO_ERROR; 00757 } 00758 00759 00760 /** 00761 * @brief Get link state 00762 * @param[in] interface Pointer to the desired network interface 00763 * @return Link state 00764 **/ 00765 00766 bool_t netGetLinkState(NetInterface *interface) 00767 { 00768 bool_t linkState; 00769 00770 //Make sure the network interface is valid 00771 if(interface == NULL) 00772 return FALSE; 00773 00774 //Get exclusive access 00775 osAcquireMutex(&netMutex); 00776 //Retrieve link state 00777 linkState = interface->linkState; 00778 //Release exclusive access 00779 osReleaseMutex(&netMutex); 00780 00781 //Return link state 00782 return linkState; 00783 } 00784 00785 00786 /** 00787 * @brief Configure network interface 00788 * @param[in] interface Network interface to configure 00789 * @return Error code 00790 **/ 00791 00792 error_t netConfigInterface(NetInterface *interface) 00793 { 00794 error_t error; 00795 00796 //Make sure the network interface is valid 00797 if(interface == NULL) 00798 return ERROR_INVALID_PARAMETER; 00799 00800 //Get exclusive access 00801 osAcquireMutex(&netMutex); 00802 00803 //Disable hardware interrupts 00804 interface->nicDriver->disableIrq(interface); 00805 00806 //Start of exception handling block 00807 do 00808 { 00809 //Receive notifications when the transmitter is ready to send 00810 if(!osCreateEvent(&interface->nicTxEvent)) 00811 { 00812 //Failed to create event object 00813 error = ERROR_OUT_OF_RESOURCES; 00814 //Stop immediately 00815 break; 00816 } 00817 00818 //Network controller initialization 00819 error = interface->nicDriver->init(interface); 00820 //Any error to report? 00821 if(error) 00822 break; 00823 00824 #if (ETH_SUPPORT == ENABLED) 00825 //Ethernet related initialization 00826 error = ethInit(interface); 00827 //Any error to report? 00828 if(error) 00829 break; 00830 00831 //Interface's physical address 00832 MIB2_SET_OCTET_STRING(interface->mibIfEntry->ifPhysAddress, &interface->macAddr, 6); 00833 MIB2_SET_OCTET_STRING_LEN(interface->mibIfEntry->ifPhysAddressLen, 6); 00834 #endif 00835 00836 #if (IPV4_SUPPORT == ENABLED) 00837 //IPv4 initialization 00838 error = ipv4Init(interface); 00839 //Any error to report? 00840 if(error) 00841 break; 00842 00843 #if (ETH_SUPPORT == ENABLED) 00844 //ARP cache initialization 00845 error = arpInit(interface); 00846 //Any error to report? 00847 if(error) 00848 break; 00849 #endif 00850 00851 #if (IGMP_SUPPORT == ENABLED) 00852 //IGMP related initialization 00853 error = igmpInit(interface); 00854 //Any error to report? 00855 if(error) 00856 break; 00857 00858 //Join the all-systems group 00859 error = ipv4JoinMulticastGroup(interface, IGMP_ALL_SYSTEMS_ADDR); 00860 //Any error to report? 00861 if(error) 00862 break; 00863 #endif 00864 00865 #if (NBNS_CLIENT_SUPPORT == ENABLED || NBNS_RESPONDER_SUPPORT == ENABLED) 00866 //NetBIOS Name Service related initialization 00867 error = nbnsInit(interface); 00868 //Any error to report? 00869 if(error) 00870 break; 00871 #endif 00872 #endif 00873 00874 #if (IPV6_SUPPORT == ENABLED) 00875 //IPv6 initialization 00876 error = ipv6Init(interface); 00877 //Any error to report? 00878 if(error) 00879 break; 00880 00881 #if (NDP_SUPPORT == ENABLED) 00882 //NDP related initialization 00883 error = ndpInit(interface); 00884 //Any error to report? 00885 if(error) 00886 break; 00887 #endif 00888 00889 #if (MLD_SUPPORT == ENABLED) 00890 //MLD related initialization 00891 error = mldInit(interface); 00892 //Any error to report? 00893 if(error) 00894 break; 00895 #endif 00896 00897 //Join the All-Nodes multicast address 00898 error = ipv6JoinMulticastGroup(interface, &IPV6_LINK_LOCAL_ALL_NODES_ADDR); 00899 //Any error to report? 00900 if(error) 00901 break; 00902 #endif 00903 00904 #if (MDNS_CLIENT_SUPPORT == ENABLED || MDNS_RESPONDER_SUPPORT == ENABLED) 00905 //mDNS related initialization 00906 error = mdnsInit(interface); 00907 //Any error to report? 00908 if(error) 00909 break; 00910 #endif 00911 00912 //End of exception handling block 00913 } while(0); 00914 00915 //Check status code 00916 if(!error) 00917 { 00918 //The network interface is now fully configured 00919 interface->configured = TRUE; 00920 00921 //Check whether the TCP/IP process is running 00922 if(netTaskRunning) 00923 { 00924 //Interrupts can be safely enabled 00925 interface->nicDriver->enableIrq(interface); 00926 } 00927 } 00928 else 00929 { 00930 //Clean up side effects before returning 00931 osDeleteEvent(&interface->nicTxEvent); 00932 } 00933 00934 //Release exclusive access 00935 osReleaseMutex(&netMutex); 00936 00937 //Return status code 00938 return error; 00939 } 00940 00941 00942 /** 00943 * @brief TCP/IP events handling 00944 **/ 00945 00946 void netTask(void) 00947 { 00948 uint_t i; 00949 bool_t status; 00950 systime_t time; 00951 systime_t timeout; 00952 NetInterface *interface; 00953 00954 #if (NET_RTOS_SUPPORT == ENABLED) 00955 //Get exclusive access 00956 osAcquireMutex(&netMutex); 00957 00958 //The TCP/IP process is now running 00959 netTaskRunning = TRUE; 00960 00961 //Loop through network interfaces 00962 for(i = 0; i < NET_INTERFACE_COUNT; i++) 00963 { 00964 //Point to the current network interface 00965 interface = &netInterface[i]; 00966 00967 //Check whether the interface is fully configured 00968 if(interface->configured) 00969 { 00970 //Interrupts can be safely enabled 00971 interface->nicDriver->enableIrq(interface); 00972 } 00973 } 00974 00975 //Release exclusive access 00976 osReleaseMutex(&netMutex); 00977 00978 //Main loop 00979 while(1) 00980 { 00981 #endif 00982 //Get current time 00983 time = osGetSystemTime(); 00984 00985 //Compute the maximum blocking time when waiting for an event 00986 if(timeCompare(time, netTimestamp) < 0) 00987 timeout = netTimestamp - time; 00988 else 00989 timeout = 0; 00990 00991 //Receive notifications when a frame has been received, or the 00992 //link state of any network interfaces has changed 00993 status = osWaitForEvent(&netEvent, timeout); 00994 00995 //Check whether the specified event is in signaled state 00996 if(status) 00997 { 00998 //Get exclusive access 00999 osAcquireMutex(&netMutex); 01000 01001 //Process events 01002 for(i = 0; i < NET_INTERFACE_COUNT; i++) 01003 { 01004 //Point to the current network interface 01005 interface = &netInterface[i]; 01006 01007 //Check whether a NIC event is pending 01008 if(interface->nicEvent) 01009 { 01010 //Acknowledge the event by clearing the flag 01011 interface->nicEvent = FALSE; 01012 01013 //Disable hardware interrupts 01014 interface->nicDriver->disableIrq(interface); 01015 //Handle NIC events 01016 interface->nicDriver->eventHandler(interface); 01017 //Re-enable hardware interrupts 01018 interface->nicDriver->enableIrq(interface); 01019 } 01020 01021 //Check whether a PHY event is pending 01022 if(interface->phyEvent) 01023 { 01024 //Acknowledge the event by clearing the flag 01025 interface->phyEvent = FALSE; 01026 01027 //Disable hardware interrupts 01028 interface->nicDriver->disableIrq(interface); 01029 //Handle PHY events 01030 interface->phyDriver->eventHandler(interface); 01031 //Re-enable hardware interrupts 01032 interface->nicDriver->enableIrq(interface); 01033 } 01034 } 01035 01036 //Release exclusive access 01037 osReleaseMutex(&netMutex); 01038 } 01039 01040 //Check current time 01041 if(timeCompare(time, netTimestamp) > 0) 01042 { 01043 //Get exclusive access 01044 osAcquireMutex(&netMutex); 01045 //Handle periodic operations 01046 netTick(); 01047 //Release exclusive access 01048 osReleaseMutex(&netMutex); 01049 01050 //Next event 01051 netTimestamp = time + NET_TICK_INTERVAL; 01052 } 01053 #if (NET_RTOS_SUPPORT == ENABLED) 01054 } 01055 #endif 01056 } 01057 01058 01059 /** 01060 * @brief Manage TCP/IP timers 01061 **/ 01062 01063 void netTick(void) 01064 { 01065 uint_t i; 01066 01067 //Increment tick counter 01068 nicTickCounter += NET_TICK_INTERVAL; 01069 01070 //Handle periodic operations such as polling the link state 01071 if(nicTickCounter >= NIC_TICK_INTERVAL) 01072 { 01073 //Loop through network interfaces 01074 for(i = 0; i < NET_INTERFACE_COUNT; i++) 01075 { 01076 //Make sure the interface has been properly configured 01077 if(netInterface[i].configured) 01078 nicTick(&netInterface[i]); 01079 } 01080 01081 //Reset tick counter 01082 nicTickCounter = 0; 01083 } 01084 01085 #if (PPP_SUPPORT == ENABLED) 01086 //Increment tick counter 01087 pppTickCounter += NET_TICK_INTERVAL; 01088 01089 //Manage PPP related timers 01090 if(pppTickCounter >= PPP_TICK_INTERVAL) 01091 { 01092 //Loop through network interfaces 01093 for(i = 0; i < NET_INTERFACE_COUNT; i++) 01094 { 01095 //Make sure the interface has been properly configured 01096 if(netInterface[i].configured) 01097 pppTick(&netInterface[i]); 01098 } 01099 01100 //Reset tick counter 01101 pppTickCounter = 0; 01102 } 01103 #endif 01104 01105 #if (IPV4_SUPPORT == ENABLED && ETH_SUPPORT == ENABLED) 01106 //Increment tick counter 01107 arpTickCounter += NET_TICK_INTERVAL; 01108 01109 //Manage ARP cache 01110 if(arpTickCounter >= ARP_TICK_INTERVAL) 01111 { 01112 //Loop through network interfaces 01113 for(i = 0; i < NET_INTERFACE_COUNT; i++) 01114 { 01115 //Make sure the interface has been properly configured 01116 if(netInterface[i].configured) 01117 arpTick(&netInterface[i]); 01118 } 01119 01120 //Reset tick counter 01121 arpTickCounter = 0; 01122 } 01123 #endif 01124 01125 #if (IPV4_SUPPORT == ENABLED && IPV4_FRAG_SUPPORT == ENABLED) 01126 //Increment tick counter 01127 ipv4FragTickCounter += NET_TICK_INTERVAL; 01128 01129 //Handle IPv4 fragment reassembly timeout 01130 if(ipv4FragTickCounter >= IPV4_FRAG_TICK_INTERVAL) 01131 { 01132 //Loop through network interfaces 01133 for(i = 0; i < NET_INTERFACE_COUNT; i++) 01134 { 01135 //Make sure the interface has been properly configured 01136 if(netInterface[i].configured) 01137 ipv4FragTick(&netInterface[i]); 01138 } 01139 01140 //Reset tick counter 01141 ipv4FragTickCounter = 0; 01142 } 01143 #endif 01144 01145 #if (IPV4_SUPPORT == ENABLED && IGMP_SUPPORT == ENABLED) 01146 //Increment tick counter 01147 igmpTickCounter += NET_TICK_INTERVAL; 01148 01149 //Handle IGMP related timers 01150 if(igmpTickCounter >= IGMP_TICK_INTERVAL) 01151 { 01152 //Loop through network interfaces 01153 for(i = 0; i < NET_INTERFACE_COUNT; i++) 01154 { 01155 //Make sure the interface has been properly configured 01156 if(netInterface[i].configured) 01157 igmpTick(&netInterface[i]); 01158 } 01159 01160 //Reset tick counter 01161 igmpTickCounter = 0; 01162 } 01163 #endif 01164 01165 #if (IPV4_SUPPORT == ENABLED && AUTO_IP_SUPPORT == ENABLED) 01166 //Increment tick counter 01167 autoIpTickCounter += NET_TICK_INTERVAL; 01168 01169 //Handle Auto-IP related timers 01170 if(autoIpTickCounter >= AUTO_IP_TICK_INTERVAL) 01171 { 01172 //Loop through network interfaces 01173 for(i = 0; i < NET_INTERFACE_COUNT; i++) 01174 autoIpTick(netInterface[i].autoIpContext); 01175 01176 //Reset tick counter 01177 autoIpTickCounter = 0; 01178 } 01179 #endif 01180 01181 #if (IPV4_SUPPORT == ENABLED && DHCP_CLIENT_SUPPORT == ENABLED) 01182 //Increment tick counter 01183 dhcpClientTickCounter += NET_TICK_INTERVAL; 01184 01185 //Handle DHCP client related timers 01186 if(dhcpClientTickCounter >= DHCP_CLIENT_TICK_INTERVAL) 01187 { 01188 //Loop through network interfaces 01189 for(i = 0; i < NET_INTERFACE_COUNT; i++) 01190 dhcpClientTick(netInterface[i].dhcpClientContext); 01191 01192 //Reset tick counter 01193 dhcpClientTickCounter = 0; 01194 } 01195 #endif 01196 01197 #if (IPV4_SUPPORT == ENABLED && DHCP_SERVER_SUPPORT == ENABLED) 01198 //Increment tick counter 01199 dhcpServerTickCounter += NET_TICK_INTERVAL; 01200 01201 //Handle DHCP server related timers 01202 if(dhcpServerTickCounter >= DHCP_SERVER_TICK_INTERVAL) 01203 { 01204 //Loop through network interfaces 01205 for(i = 0; i < NET_INTERFACE_COUNT; i++) 01206 dhcpServerTick(netInterface[i].dhcpServerContext); 01207 01208 //Reset tick counter 01209 dhcpServerTickCounter = 0; 01210 } 01211 #endif 01212 01213 #if (IPV6_SUPPORT == ENABLED && IPV6_FRAG_SUPPORT == ENABLED) 01214 //Increment tick counter 01215 ipv6FragTickCounter += NET_TICK_INTERVAL; 01216 01217 //Handle IPv6 fragment reassembly timeout 01218 if(ipv6FragTickCounter >= IPV6_FRAG_TICK_INTERVAL) 01219 { 01220 //Loop through network interfaces 01221 for(i = 0; i < NET_INTERFACE_COUNT; i++) 01222 { 01223 //Make sure the interface has been properly configured 01224 if(netInterface[i].configured) 01225 ipv6FragTick(&netInterface[i]); 01226 } 01227 01228 //Reset tick counter 01229 ipv6FragTickCounter = 0; 01230 } 01231 #endif 01232 01233 #if (IPV6_SUPPORT == ENABLED && MLD_SUPPORT == ENABLED) 01234 //Increment tick counter 01235 mldTickCounter += NET_TICK_INTERVAL; 01236 01237 //Handle MLD related timers 01238 if(mldTickCounter >= MLD_TICK_INTERVAL) 01239 { 01240 //Loop through network interfaces 01241 for(i = 0; i < NET_INTERFACE_COUNT; i++) 01242 { 01243 //Make sure the interface has been properly configured 01244 if(netInterface[i].configured) 01245 mldTick(&netInterface[i]); 01246 } 01247 01248 //Reset tick counter 01249 mldTickCounter = 0; 01250 } 01251 #endif 01252 01253 #if (IPV6_SUPPORT == ENABLED && NDP_SUPPORT == ENABLED) 01254 //Increment tick counter 01255 ndpTickCounter += NET_TICK_INTERVAL; 01256 01257 //Handle NDP related timers 01258 if(ndpTickCounter >= NDP_TICK_INTERVAL) 01259 { 01260 //Loop through network interfaces 01261 for(i = 0; i < NET_INTERFACE_COUNT; i++) 01262 { 01263 //Make sure the interface has been properly configured 01264 if(netInterface[i].configured) 01265 ndpTick(&netInterface[i]); 01266 } 01267 01268 //Reset tick counter 01269 ndpTickCounter = 0; 01270 } 01271 #endif 01272 01273 #if (IPV6_SUPPORT == ENABLED && NDP_ROUTER_ADV_SUPPORT == ENABLED) 01274 //Increment tick counter 01275 ndpRouterAdvTickCounter += NET_TICK_INTERVAL; 01276 01277 //Handle RA service related timers 01278 if(ndpRouterAdvTickCounter >= NDP_ROUTER_ADV_TICK_INTERVAL) 01279 { 01280 //Loop through network interfaces 01281 for(i = 0; i < NET_INTERFACE_COUNT; i++) 01282 ndpRouterAdvTick(netInterface[i].ndpRouterAdvContext); 01283 01284 //Reset tick counter 01285 ndpRouterAdvTickCounter = 0; 01286 } 01287 #endif 01288 01289 #if (IPV6_SUPPORT == ENABLED && DHCPV6_CLIENT_SUPPORT == ENABLED) 01290 //Increment tick counter 01291 dhcpv6ClientTickCounter += NET_TICK_INTERVAL; 01292 01293 //Handle DHCPv6 client related timers 01294 if(dhcpv6ClientTickCounter >= DHCPV6_CLIENT_TICK_INTERVAL) 01295 { 01296 //Loop through network interfaces 01297 for(i = 0; i < NET_INTERFACE_COUNT; i++) 01298 dhcpv6ClientTick(netInterface[i].dhcpv6ClientContext); 01299 01300 //Reset tick counter 01301 dhcpv6ClientTickCounter = 0; 01302 } 01303 #endif 01304 01305 #if (TCP_SUPPORT == ENABLED) 01306 //Increment tick counter 01307 tcpTickCounter += NET_TICK_INTERVAL; 01308 01309 //Manage TCP related timers 01310 if(tcpTickCounter >= TCP_TICK_INTERVAL) 01311 { 01312 //TCP timer handler 01313 tcpTick(); 01314 //Reset tick counter 01315 tcpTickCounter = 0; 01316 } 01317 #endif 01318 01319 #if (DNS_CLIENT_SUPPORT == ENABLED || MDNS_CLIENT_SUPPORT == ENABLED || \ 01320 NBNS_CLIENT_SUPPORT == ENABLED) 01321 //Increment tick counter 01322 dnsTickCounter += NET_TICK_INTERVAL; 01323 01324 //Manage DNS cache 01325 if(dnsTickCounter >= DNS_TICK_INTERVAL) 01326 { 01327 //DNS timer handler 01328 dnsTick(); 01329 //Reset tick counter 01330 dnsTickCounter = 0; 01331 } 01332 #endif 01333 01334 #if (MDNS_RESPONDER_SUPPORT == ENABLED) 01335 //Increment tick counter 01336 mdnsResponderTickCounter += NET_TICK_INTERVAL; 01337 01338 //Manage mDNS probing and announcing 01339 if(mdnsResponderTickCounter >= MDNS_RESPONDER_TICK_INTERVAL) 01340 { 01341 //Loop through network interfaces 01342 for(i = 0; i < NET_INTERFACE_COUNT; i++) 01343 mdnsResponderTick(netInterface[i].mdnsResponderContext); 01344 01345 //Reset tick counter 01346 mdnsResponderTickCounter = 0; 01347 } 01348 #endif 01349 01350 #if (DNS_SD_SUPPORT == ENABLED) 01351 //Increment tick counter 01352 dnsSdTickCounter += NET_TICK_INTERVAL; 01353 01354 //Manage DNS-SD probing and announcing 01355 if(dnsSdTickCounter >= DNS_SD_TICK_INTERVAL) 01356 { 01357 //Loop through network interfaces 01358 for(i = 0; i < NET_INTERFACE_COUNT; i++) 01359 dnsSdTick(netInterface[i].dnsSdContext); 01360 01361 //Reset tick counter 01362 dnsSdTickCounter = 0; 01363 } 01364 #endif 01365 } 01366 01367 01368 /** 01369 * @brief Get default network interface 01370 * @return Pointer to the default network interface to be used 01371 **/ 01372 01373 NetInterface *netGetDefaultInterface(void) 01374 { 01375 //Default network interface 01376 return &netInterface[0]; 01377 } 01378 01379 01380 /** 01381 * @brief Seed pseudo-random number generator 01382 * @param[in] seed An integer value to be used as seed by the pseudo-random number generator 01383 * @return Error code 01384 **/ 01385 01386 error_t netInitRand(uint32_t seed) 01387 { 01388 //Seed the pseudo-random number generator 01389 prngState += seed; 01390 01391 //Successful processing 01392 return NO_ERROR; 01393 } 01394 01395 01396 /** 01397 * @brief Get a random value 01398 * @return Error code 01399 **/ 01400 01401 uint32_t netGetRand(void) 01402 { 01403 uint32_t result; 01404 01405 //Use a linear congruential generator (LCG) to update the state of the PRNG 01406 prngState *= 1103515245; 01407 prngState += 12345; 01408 result = (prngState >> 16) & 0x07FF; 01409 01410 prngState *= 1103515245; 01411 prngState += 12345; 01412 result <<= 10; 01413 result |= (prngState >> 16) & 0x03FF; 01414 01415 prngState *= 1103515245; 01416 prngState += 12345; 01417 result <<= 10; 01418 result |= (prngState >> 16) & 0x03FF; 01419 01420 //Return the resulting value 01421 return result; 01422 } 01423 01424 01425 /** 01426 * @brief Get a random value in the specified range 01427 * @param[in] min Lower bound 01428 * @param[in] max Upper bound 01429 * @return Random value in the specified range 01430 **/ 01431 01432 int32_t netGetRandRange(int32_t min, int32_t max) 01433 { 01434 //Return a random value in the given range 01435 return min + netGetRand() % (max - min + 1); 01436 } 01437 01438 01439 /** 01440 * @brief Register link change callback 01441 * @param[in] interface Underlying network interface 01442 * @param[in] callback Callback function to be called when the link state changed 01443 * @param[in] params Callback function parameter (optional) 01444 * @param[out] cookie Identifier that can be used to unregister the callback function 01445 * @return Error code 01446 **/ 01447 01448 error_t netAttachLinkChangeCallback(NetInterface *interface, 01449 LinkChangeCallback callback, void *params, uint_t *cookie) 01450 { 01451 uint_t i; 01452 LinkChangeCallbackDesc *entry; 01453 01454 //Acquire exclusive access to the callback table 01455 osAcquireMutex(&callbackTableMutex); 01456 01457 //Loop through the table 01458 for(i = 0; i < NET_CALLBACK_TABLE_SIZE; i++) 01459 { 01460 //Point to the current entry 01461 entry = &callbackTable[i]; 01462 01463 //Check whether the entry is currently in used 01464 if(entry->callback == NULL) 01465 { 01466 //Create a new entry 01467 entry->interface = interface; 01468 entry->callback = callback; 01469 entry->params = params; 01470 //We are done 01471 break; 01472 } 01473 } 01474 01475 //Release exclusive access to the callback table 01476 osReleaseMutex(&callbackTableMutex); 01477 01478 //Failed to attach the specified user callback? 01479 if(i >= NET_CALLBACK_TABLE_SIZE) 01480 return ERROR_OUT_OF_RESOURCES; 01481 01482 //Return a cookie that can be used later to unregister the callback 01483 if(cookie != NULL) 01484 *cookie = i; 01485 01486 //Successful processing 01487 return NO_ERROR; 01488 } 01489 01490 01491 /** 01492 * @brief Unregister link change callback 01493 * @param[in] cookie Identifier specifying the callback to be unregistered 01494 * @return Error code 01495 **/ 01496 01497 error_t netDetachLinkChangeCallback(uint_t cookie) 01498 { 01499 //Make sure the cookie is valid 01500 if(cookie >= NET_CALLBACK_TABLE_SIZE) 01501 return ERROR_INVALID_PARAMETER; 01502 01503 //Acquire exclusive access to the callback table 01504 osAcquireMutex(&callbackTableMutex); 01505 //Unregister user callback 01506 callbackTable[cookie].callback = NULL; 01507 //Release exclusive access to the callback table 01508 osReleaseMutex(&callbackTableMutex); 01509 01510 //Successful processing 01511 return NO_ERROR; 01512 } 01513 01514 01515 /** 01516 * @brief Invoke link change callback 01517 * @param[in] interface Underlying network interface 01518 * @param[in] linkState Link state 01519 **/ 01520 01521 void netInvokeLinkChangeCallback(NetInterface *interface, bool_t linkState) 01522 { 01523 uint_t i; 01524 LinkChangeCallbackDesc *entry; 01525 01526 //Acquire exclusive access to the callback table 01527 osAcquireMutex(&callbackTableMutex); 01528 01529 //Loop through the table 01530 for(i = 0; i < NET_CALLBACK_TABLE_SIZE; i++) 01531 { 01532 //Point to the current entry 01533 entry = &callbackTable[i]; 01534 01535 //Any registered callback? 01536 if(entry->callback != NULL) 01537 { 01538 //Check whether the network interface matches the current entry 01539 if(entry->interface == NULL || entry->interface == interface) 01540 { 01541 //Invoke user callback function 01542 entry->callback(interface, linkState, entry->params); 01543 } 01544 } 01545 } 01546 01547 //Release exclusive access to the callback table 01548 osReleaseMutex(&callbackTableMutex); 01549 } 01550
Generated on Tue Jul 12 2022 17:10:15 by
1.7.2