Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
net.c
Go to the documentation of this file.
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
