Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
raw_socket.c
Go to the documentation of this file.
00001 /** 00002 * @file raw_socket.c 00003 * @brief TCP/IP raw sockets 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 * @section Description 00026 * 00027 * A raw socket is a type of socket that allows access to the 00028 * underlying transport provider 00029 * 00030 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00031 * @version 1.7.6 00032 **/ 00033 00034 //Switch to the appropriate trace level 00035 #define TRACE_LEVEL RAW_SOCKET_TRACE_LEVEL 00036 00037 //Dependencies 00038 #include <string.h> 00039 #include "core/net.h" 00040 #include "ipv4/ipv4.h" 00041 #include "ipv6/ipv6.h" 00042 #include "ipv6/ipv6_misc.h" 00043 #include "core/raw_socket.h" 00044 #include "core/socket.h" 00045 #include "core/ethernet.h" 00046 #include "debug.h" 00047 00048 //Check TCP/IP stack configuration 00049 #if (RAW_SOCKET_SUPPORT == ENABLED) 00050 00051 00052 /** 00053 * @brief Process incoming IP packet 00054 * @param[in] interface Underlying network interface 00055 * @param[in] pseudoHeader IPv4 or IPv6 pseudo header 00056 * @param[in] buffer Multi-part buffer containing the IP packet 00057 * @param[in] offset Offset to the first byte of the IP packet 00058 * @return Error code 00059 **/ 00060 00061 error_t rawSocketProcessIpPacket(NetInterface *interface, 00062 IpPseudoHeader *pseudoHeader, const NetBuffer *buffer, size_t offset) 00063 { 00064 uint_t i; 00065 size_t length; 00066 Socket *socket; 00067 SocketQueueItem *queueItem; 00068 NetBuffer *p; 00069 00070 //Retrieve the length of the raw IP packet 00071 length = netBufferGetLength(buffer) - offset; 00072 00073 //Loop through opened sockets 00074 for(i = 0; i < SOCKET_MAX_COUNT; i++) 00075 { 00076 //Point to the current socket 00077 socket = socketTable + i; 00078 00079 //Raw socket found? 00080 if(socket->type != SOCKET_TYPE_RAW_IP) 00081 continue; 00082 //Check whether the socket is bound to a particular interface 00083 if(socket->interface && socket->interface != interface) 00084 continue; 00085 00086 #if (IPV4_SUPPORT == ENABLED) 00087 //An IPv4 packet was received? 00088 if(pseudoHeader->length == sizeof(Ipv4PseudoHeader)) 00089 { 00090 //Check protocol field 00091 if(socket->protocol != pseudoHeader->ipv4Data.protocol) 00092 continue; 00093 //Destination IP address filtering 00094 if(socket->localIpAddr.length) 00095 { 00096 //An IPv4 address is expected 00097 if(socket->localIpAddr.length != sizeof(Ipv4Addr)) 00098 continue; 00099 //Filter out non-matching addresses 00100 if(socket->localIpAddr.ipv4Addr != pseudoHeader->ipv4Data.destAddr) 00101 continue; 00102 } 00103 //Source IP address filtering 00104 if(socket->remoteIpAddr.length) 00105 { 00106 //An IPv4 address is expected 00107 if(socket->remoteIpAddr.length != sizeof(Ipv4Addr)) 00108 continue; 00109 //Filter out non-matching addresses 00110 if(socket->remoteIpAddr.ipv4Addr != pseudoHeader->ipv4Data.srcAddr) 00111 continue; 00112 } 00113 } 00114 else 00115 #endif 00116 #if (IPV6_SUPPORT == ENABLED) 00117 //An IPv6 packet was received? 00118 if(pseudoHeader->length == sizeof(Ipv6PseudoHeader)) 00119 { 00120 //Check protocol field 00121 if(socket->protocol != pseudoHeader->ipv6Data.nextHeader) 00122 continue; 00123 00124 //Destination IP address filtering 00125 if(socket->localIpAddr.length) 00126 { 00127 //An IPv6 address is expected 00128 if(socket->localIpAddr.length != sizeof(Ipv6Addr)) 00129 continue; 00130 //Filter out non-matching addresses 00131 if(!ipv6CompAddr(&socket->localIpAddr.ipv6Addr, &pseudoHeader->ipv6Data.destAddr)) 00132 continue; 00133 } 00134 00135 //Source IP address filtering 00136 if(socket->remoteIpAddr.length) 00137 { 00138 //An IPv6 address is expected 00139 if(socket->remoteIpAddr.length != sizeof(Ipv6Addr)) 00140 continue; 00141 //Filter out non-matching addresses 00142 if(!ipv6CompAddr(&socket->remoteIpAddr.ipv6Addr, &pseudoHeader->ipv6Data.srcAddr)) 00143 continue; 00144 } 00145 } 00146 else 00147 #endif 00148 //An invalid packet was received? 00149 { 00150 //This should never occur... 00151 continue; 00152 } 00153 00154 //The current socket meets all the criteria 00155 break; 00156 } 00157 00158 //Drop incoming packet if no matching socket was found 00159 if(i >= SOCKET_MAX_COUNT) 00160 return ERROR_PROTOCOL_UNREACHABLE; 00161 00162 //Empty receive queue? 00163 if(!socket->receiveQueue) 00164 { 00165 //Allocate a memory buffer to hold the data and the associated descriptor 00166 p = netBufferAlloc(sizeof(SocketQueueItem) + length); 00167 00168 //Successful memory allocation? 00169 if(p != NULL) 00170 { 00171 //Point to the newly created item 00172 queueItem = netBufferAt(p, 0); 00173 queueItem->buffer = p; 00174 //Add the newly created item to the queue 00175 socket->receiveQueue = queueItem; 00176 } 00177 else 00178 { 00179 //Memory allocation failed 00180 queueItem = NULL; 00181 } 00182 } 00183 else 00184 { 00185 //Point to the very first item 00186 queueItem = socket->receiveQueue; 00187 //Reach the last item in the receive queue 00188 for(i = 1; queueItem->next; i++) 00189 queueItem = queueItem->next; 00190 00191 //Make sure the receive queue is not full 00192 if(i >= RAW_SOCKET_RX_QUEUE_SIZE) 00193 return ERROR_RECEIVE_QUEUE_FULL; 00194 00195 //Allocate a memory buffer to hold the data and the associated descriptor 00196 p = netBufferAlloc(sizeof(SocketQueueItem) + length); 00197 00198 //Successful memory allocation? 00199 if(p != NULL) 00200 { 00201 //Add the newly created item to the queue 00202 queueItem->next = netBufferAt(p, 0); 00203 //Point to the newly created item 00204 queueItem = queueItem->next; 00205 queueItem->buffer = p; 00206 } 00207 else 00208 { 00209 //Memory allocation failed 00210 queueItem = NULL; 00211 } 00212 } 00213 00214 //Failed to allocate memory? 00215 if(queueItem == NULL) 00216 return ERROR_OUT_OF_MEMORY; 00217 00218 //Initialize next field 00219 queueItem->next = NULL; 00220 //Port number is unused 00221 queueItem->srcPort = 0; 00222 00223 #if (IPV4_SUPPORT == ENABLED) 00224 //IPv4 remote address? 00225 if(pseudoHeader->length == sizeof(Ipv4PseudoHeader)) 00226 { 00227 //Save the source IPv4 address 00228 queueItem->srcIpAddr.length = sizeof(Ipv4Addr); 00229 queueItem->srcIpAddr.ipv4Addr = pseudoHeader->ipv4Data.srcAddr; 00230 //Save the destination IPv4 address 00231 queueItem->destIpAddr.length = sizeof(Ipv4Addr); 00232 queueItem->destIpAddr.ipv4Addr = pseudoHeader->ipv4Data.destAddr; 00233 } 00234 #endif 00235 #if (IPV6_SUPPORT == ENABLED) 00236 //IPv6 remote address? 00237 if(pseudoHeader->length == sizeof(Ipv6PseudoHeader)) 00238 { 00239 //Save the source IPv6 address 00240 queueItem->srcIpAddr.length = sizeof(Ipv6Addr); 00241 queueItem->srcIpAddr.ipv6Addr = pseudoHeader->ipv6Data.srcAddr; 00242 //Save the destination IPv6 address 00243 queueItem->destIpAddr.length = sizeof(Ipv6Addr); 00244 queueItem->destIpAddr.ipv6Addr = pseudoHeader->ipv6Data.destAddr; 00245 } 00246 #endif 00247 00248 //Offset to the raw IP packet 00249 queueItem->offset = sizeof(SocketQueueItem); 00250 //Copy the raw data 00251 netBufferCopy(queueItem->buffer, queueItem->offset, buffer, offset, length); 00252 00253 //Notify user that data is available 00254 rawSocketUpdateEvents(socket); 00255 00256 //Successful processing 00257 return NO_ERROR; 00258 } 00259 00260 00261 /** 00262 * @brief Process incoming Ethernet packet 00263 * @param[in] interface Underlying network interface 00264 * @param[in] ethFrame Incoming Ethernet frame to process 00265 * @param[in] length Total frame length 00266 **/ 00267 00268 void rawSocketProcessEthPacket(NetInterface *interface, 00269 EthHeader *ethFrame, size_t length) 00270 { 00271 uint_t i; 00272 Socket *socket; 00273 SocketQueueItem *queueItem; 00274 NetBuffer *p; 00275 00276 //Loop through opened sockets 00277 for(i = 0; i < SOCKET_MAX_COUNT; i++) 00278 { 00279 //Point to the current socket 00280 socket = socketTable + i; 00281 00282 //Raw socket found? 00283 if(socket->type != SOCKET_TYPE_RAW_ETH) 00284 continue; 00285 //Check whether the socket is bound to a particular interface 00286 if(socket->interface && socket->interface != interface) 00287 continue; 00288 //Check protocol field 00289 if(socket->protocol != SOCKET_ETH_PROTO_ALL && socket->protocol != ntohs(ethFrame->type)) 00290 continue; 00291 00292 //The current socket meets all the criteria 00293 break; 00294 } 00295 00296 //Drop incoming packet if no matching socket was found 00297 if(i >= SOCKET_MAX_COUNT) 00298 return; 00299 00300 //Empty receive queue? 00301 if(!socket->receiveQueue) 00302 { 00303 //Allocate a memory buffer to hold the data and the associated descriptor 00304 p = netBufferAlloc(sizeof(SocketQueueItem) + length); 00305 00306 //Successful memory allocation? 00307 if(p != NULL) 00308 { 00309 //Point to the newly created item 00310 queueItem = netBufferAt(p, 0); 00311 queueItem->buffer = p; 00312 //Add the newly created item to the queue 00313 socket->receiveQueue = queueItem; 00314 } 00315 else 00316 { 00317 //Memory allocation failed 00318 queueItem = NULL; 00319 } 00320 } 00321 else 00322 { 00323 //Point to the very first item 00324 queueItem = socket->receiveQueue; 00325 //Reach the last item in the receive queue 00326 for(i = 1; queueItem->next; i++) 00327 queueItem = queueItem->next; 00328 00329 //Make sure the receive queue is not full 00330 if(i >= RAW_SOCKET_RX_QUEUE_SIZE) 00331 return; 00332 00333 //Allocate a memory buffer to hold the data and the associated descriptor 00334 p = netBufferAlloc(sizeof(SocketQueueItem) + length); 00335 00336 //Successful memory allocation? 00337 if(p != NULL) 00338 { 00339 //Add the newly created item to the queue 00340 queueItem->next = netBufferAt(p, 0); 00341 //Point to the newly created item 00342 queueItem = queueItem->next; 00343 queueItem->buffer = p; 00344 } 00345 else 00346 { 00347 //Memory allocation failed 00348 queueItem = NULL; 00349 } 00350 } 00351 00352 //Failed to allocate memory? 00353 if(queueItem == NULL) 00354 return; 00355 00356 //Initialize next field 00357 queueItem->next = NULL; 00358 //Other fields are meaningless 00359 queueItem->srcPort = 0; 00360 queueItem->srcIpAddr = IP_ADDR_ANY; 00361 queueItem->destIpAddr = IP_ADDR_ANY; 00362 00363 //Offset to the raw datagram 00364 queueItem->offset = sizeof(SocketQueueItem); 00365 //Copy the raw data 00366 netBufferWrite(queueItem->buffer, queueItem->offset, ethFrame, length); 00367 00368 //Notify user that data is available 00369 rawSocketUpdateEvents(socket); 00370 } 00371 00372 00373 /** 00374 * @brief Send an raw IP packet 00375 * @param[in] socket Handle referencing the socket 00376 * @param[in] destIpAddr IP address of the target host 00377 * @param[in] data Pointer to raw data 00378 * @param[in] length Length of the raw data 00379 * @param[out] written Actual number of bytes written (optional parameter) 00380 * @return Error code 00381 **/ 00382 00383 error_t rawSocketSendIpPacket(Socket *socket, const IpAddr *destIpAddr, 00384 const void *data, size_t length, size_t *written) 00385 { 00386 error_t error; 00387 size_t offset; 00388 NetBuffer *buffer; 00389 NetInterface *interface; 00390 IpPseudoHeader pseudoHeader; 00391 00392 //The socket may be bound to a particular network interface 00393 interface = socket->interface; 00394 00395 //Allocate a buffer memory to hold the raw IP datagram 00396 buffer = ipAllocBuffer(0, &offset); 00397 //Failed to allocate memory? 00398 if(buffer == NULL) 00399 return ERROR_OUT_OF_MEMORY; 00400 00401 //Start of exception handling block 00402 do 00403 { 00404 //Copy the raw data 00405 error = netBufferAppend(buffer, data, length); 00406 //Any error to report? 00407 if(error) 00408 break; 00409 00410 #if (IPV4_SUPPORT == ENABLED) 00411 //Destination address is an IPv4 address? 00412 if(destIpAddr->length == sizeof(Ipv4Addr)) 00413 { 00414 Ipv4Addr srcIpAddr; 00415 00416 //Select the source IPv4 address and the relevant network interface 00417 //to use when sending data to the specified destination host 00418 error = ipv4SelectSourceAddr(&interface, destIpAddr->ipv4Addr, &srcIpAddr); 00419 //Any error to report? 00420 if(error) 00421 break; 00422 00423 //Format IPv4 pseudo header 00424 pseudoHeader.length = sizeof(Ipv4PseudoHeader); 00425 pseudoHeader.ipv4Data.srcAddr = srcIpAddr; 00426 pseudoHeader.ipv4Data.destAddr = destIpAddr->ipv4Addr; 00427 pseudoHeader.ipv4Data.reserved = 0; 00428 pseudoHeader.ipv4Data.protocol = socket->protocol; 00429 pseudoHeader.ipv4Data.length = htons(length); 00430 } 00431 else 00432 #endif 00433 #if (IPV6_SUPPORT == ENABLED) 00434 //Destination address is an IPv6 address? 00435 if(destIpAddr->length == sizeof(Ipv6Addr)) 00436 { 00437 //Select the source IPv6 address and the relevant network interface 00438 //to use when sending data to the specified destination host 00439 error = ipv6SelectSourceAddr(&interface, 00440 &destIpAddr->ipv6Addr, &pseudoHeader.ipv6Data.srcAddr); 00441 //Any error to report? 00442 if(error) 00443 break; 00444 00445 //Format IPv6 pseudo header 00446 pseudoHeader.length = sizeof(Ipv6PseudoHeader); 00447 pseudoHeader.ipv6Data.destAddr = destIpAddr->ipv6Addr; 00448 pseudoHeader.ipv6Data.length = htonl(length); 00449 pseudoHeader.ipv6Data.reserved = 0; 00450 pseudoHeader.ipv6Data.nextHeader = socket->protocol; 00451 } 00452 else 00453 #endif 00454 //Invalid destination address? 00455 { 00456 //An internal error has occurred 00457 error = ERROR_FAILURE; 00458 //Exit immediately 00459 break; 00460 } 00461 00462 //Send raw IP datagram 00463 error = ipSendDatagram(interface, &pseudoHeader, buffer, offset, socket->ttl); 00464 //Failed to send data? 00465 if(error) 00466 break; 00467 00468 //Total number of bytes successfully transmitted 00469 if(written != NULL) 00470 *written = length; 00471 00472 //End of exception handling block 00473 } while(0); 00474 00475 //Free previously allocated memory block 00476 netBufferFree(buffer); 00477 //Return status code 00478 return error; 00479 } 00480 00481 00482 /** 00483 * @brief Send an raw Ethernet packet 00484 * @param[in] socket Handle referencing the socket 00485 * @param[in] data Pointer to raw data 00486 * @param[in] length Length of the raw data 00487 * @param[out] written Actual number of bytes written (optional parameter) 00488 * @return Error code 00489 **/ 00490 00491 error_t rawSocketSendEthPacket(Socket *socket, 00492 const void *data, size_t length, size_t *written) 00493 { 00494 error_t error; 00495 00496 #if (ETH_SUPPORT == ENABLED) 00497 NetBuffer *buffer; 00498 NetInterface *interface; 00499 00500 //Select the relevant network interface 00501 if(!socket->interface) 00502 interface = netGetDefaultInterface(); 00503 else 00504 interface = socket->interface; 00505 00506 //Ethernet interface? 00507 if(interface->nicDriver->type == NIC_TYPE_ETHERNET) 00508 { 00509 //Allocate a buffer memory to hold the raw Ethernet packet 00510 buffer = netBufferAlloc(0); 00511 //Failed to allocate buffer? 00512 if(buffer == NULL) 00513 return ERROR_OUT_OF_MEMORY; 00514 00515 //Copy the raw data 00516 error = netBufferAppend(buffer, data, length); 00517 00518 //Successful processing? 00519 if(!error) 00520 { 00521 //Automatic padding not supported by hardware? 00522 if(!interface->nicDriver->autoPadding) 00523 { 00524 //The host controller should manually add padding 00525 //to the packet before transmitting it 00526 if(length < (ETH_MIN_FRAME_SIZE - ETH_CRC_SIZE)) 00527 { 00528 size_t n; 00529 00530 //Add padding as necessary 00531 n = (ETH_MIN_FRAME_SIZE - ETH_CRC_SIZE) - length; 00532 00533 //Append padding bytes 00534 error = netBufferAppend(buffer, ethPadding, n); 00535 //Any error to report? 00536 if(error) 00537 return error; 00538 00539 //Adjust frame length 00540 length += n; 00541 } 00542 } 00543 00544 //CRC calculation not supported by hardware? 00545 if(!interface->nicDriver->autoCrcCalc) 00546 { 00547 uint32_t crc; 00548 00549 //Compute CRC over the header and payload 00550 crc = ethCalcCrcEx(buffer, 0, length); 00551 //Convert from host byte order to little-endian byte order 00552 crc = htole32(crc); 00553 00554 //Append the calculated CRC value 00555 error = netBufferAppend(buffer, &crc, sizeof(crc)); 00556 //Any error to report? 00557 if(error) 00558 return error; 00559 00560 //Adjust frame length 00561 length += sizeof(crc); 00562 } 00563 00564 //Debug message 00565 TRACE_DEBUG("Sending raw Ethernet frame (%" PRIuSIZE " bytes)...\r\n", length); 00566 00567 //Send the resulting packet over the specified link 00568 error = nicSendPacket(interface, buffer, 0); 00569 } 00570 00571 //Free previously allocated memory block 00572 netBufferFree(buffer); 00573 } 00574 else 00575 #endif 00576 //Unknown interface type? 00577 { 00578 //Report an error 00579 error = ERROR_INVALID_INTERFACE; 00580 } 00581 00582 //Successful processing? 00583 if(!error) 00584 { 00585 //Total number of bytes successfully transmitted 00586 if(written != NULL) 00587 *written = length; 00588 } 00589 00590 //Return status code 00591 return error; 00592 } 00593 00594 00595 /** 00596 * @brief Receive an IP packet from a raw socket 00597 * @param[in] socket Handle referencing the socket 00598 * @param[out] srcIpAddr Source IP address (optional) 00599 * @param[out] destIpAddr Destination IP address (optional) 00600 * @param[out] data Buffer where to store the incoming data 00601 * @param[in] size Maximum number of bytes that can be received 00602 * @param[out] received Number of bytes that have been received 00603 * @param[in] flags Set of flags that influences the behavior of this function 00604 * @return Error code 00605 **/ 00606 00607 error_t rawSocketReceiveIpPacket(Socket *socket, IpAddr *srcIpAddr, 00608 IpAddr *destIpAddr, void *data, size_t size, size_t *received, uint_t flags) 00609 { 00610 SocketQueueItem *queueItem; 00611 00612 //The SOCKET_FLAG_DONT_WAIT enables non-blocking operation 00613 if(!(flags & SOCKET_FLAG_DONT_WAIT)) 00614 { 00615 //The receive queue is empty? 00616 if(!socket->receiveQueue) 00617 { 00618 //Set the events the application is interested in 00619 socket->eventMask = SOCKET_EVENT_RX_READY; 00620 //Reset the event object 00621 osResetEvent(&socket->event); 00622 00623 //Release exclusive access 00624 osReleaseMutex(&netMutex); 00625 //Wait until an event is triggered 00626 osWaitForEvent(&socket->event, socket->timeout); 00627 //Get exclusive access 00628 osAcquireMutex(&netMutex); 00629 } 00630 } 00631 00632 //Check whether the read operation timed out 00633 if(!socket->receiveQueue) 00634 { 00635 //No data can be read 00636 *received = 0; 00637 //Report a timeout error 00638 return ERROR_TIMEOUT; 00639 } 00640 00641 //Point to the first item in the receive queue 00642 queueItem = socket->receiveQueue; 00643 //Copy data to user buffer 00644 *received = netBufferRead(data, queueItem->buffer, queueItem->offset, size); 00645 00646 //Save the source IP address 00647 if(srcIpAddr) 00648 *srcIpAddr = queueItem->srcIpAddr; 00649 //Save the destination IP address 00650 if(destIpAddr) 00651 *destIpAddr = queueItem->destIpAddr; 00652 00653 //If the SOCKET_FLAG_PEEK flag is set, the data is copied 00654 //into the buffer but is not removed from the input queue 00655 if(!(flags & SOCKET_FLAG_PEEK)) 00656 { 00657 //Remove the item from the receive queue 00658 socket->receiveQueue = queueItem->next; 00659 //Deallocate memory buffer 00660 netBufferFree(queueItem->buffer); 00661 } 00662 00663 //Update the state of events 00664 rawSocketUpdateEvents(socket); 00665 00666 //Successful read operation 00667 return NO_ERROR; 00668 } 00669 00670 00671 /** 00672 * @brief Receive an Ethernet packet from a raw socket 00673 * @param[in] socket Handle referencing the socket 00674 * @param[out] data Buffer where to store the incoming data 00675 * @param[in] size Maximum number of bytes that can be received 00676 * @param[out] received Number of bytes that have been received 00677 * @param[in] flags Set of flags that influences the behavior of this function 00678 * @return Error code 00679 **/ 00680 00681 error_t rawSocketReceiveEthPacket(Socket *socket, 00682 void *data, size_t size, size_t *received, uint_t flags) 00683 { 00684 SocketQueueItem *queueItem; 00685 00686 //The SOCKET_FLAG_DONT_WAIT enables non-blocking operation 00687 if(!(flags & SOCKET_FLAG_DONT_WAIT)) 00688 { 00689 //The receive queue is empty? 00690 if(!socket->receiveQueue) 00691 { 00692 //Set the events the application is interested in 00693 socket->eventMask = SOCKET_EVENT_RX_READY; 00694 //Reset the event object 00695 osResetEvent(&socket->event); 00696 00697 //Release exclusive access 00698 osReleaseMutex(&netMutex); 00699 //Wait until an event is triggered 00700 osWaitForEvent(&socket->event, socket->timeout); 00701 //Get exclusive access 00702 osAcquireMutex(&netMutex); 00703 } 00704 } 00705 00706 //Check whether the read operation timed out 00707 if(!socket->receiveQueue) 00708 { 00709 //No data can be read 00710 *received = 0; 00711 //Report a timeout error 00712 return ERROR_TIMEOUT; 00713 } 00714 00715 //Point to the first item in the receive queue 00716 queueItem = socket->receiveQueue; 00717 //Copy data to user buffer 00718 *received = netBufferRead(data, queueItem->buffer, queueItem->offset, size); 00719 00720 //If the SOCKET_FLAG_PEEK flag is set, the data is copied 00721 //into the buffer but is not removed from the input queue 00722 if(!(flags & SOCKET_FLAG_PEEK)) 00723 { 00724 //Remove the item from the receive queue 00725 socket->receiveQueue = queueItem->next; 00726 //Deallocate memory buffer 00727 netBufferFree(queueItem->buffer); 00728 } 00729 00730 //Update the state of events 00731 rawSocketUpdateEvents(socket); 00732 00733 //Successful read operation 00734 return NO_ERROR; 00735 } 00736 00737 00738 /** 00739 * @brief Update event state for raw sockets 00740 * @param[in] socket Handle referencing the socket 00741 **/ 00742 00743 void rawSocketUpdateEvents(Socket *socket) 00744 { 00745 //Clear event flags 00746 socket->eventFlags = 0; 00747 00748 //The socket is marked as readable if a datagram is pending in the queue 00749 if(socket->receiveQueue) 00750 socket->eventFlags |= SOCKET_EVENT_RX_READY; 00751 00752 //Check whether the socket is bound to a particular network interface 00753 if(socket->interface != NULL) 00754 { 00755 //Handle link up and link down events 00756 if(socket->interface->linkState) 00757 socket->eventFlags |= SOCKET_EVENT_LINK_UP; 00758 else 00759 socket->eventFlags |= SOCKET_EVENT_LINK_DOWN; 00760 } 00761 00762 //Mask unused events 00763 socket->eventFlags &= socket->eventMask; 00764 00765 //Any event to signal? 00766 if(socket->eventFlags) 00767 { 00768 //Unblock I/O operations currently in waiting state 00769 osSetEvent(&socket->event); 00770 00771 //Set user event to signaled state if necessary 00772 if(socket->userEvent != NULL) 00773 osSetEvent(socket->userEvent); 00774 } 00775 } 00776 00777 #endif 00778
Generated on Tue Jul 12 2022 17:10:15 by
