bsd_socket.c
Go to the documentation of this file.
1 /**
2  * @file bsd_socket.c
3  * @brief BSD socket API
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 1.9.6
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL BSD_SOCKET_TRACE_LEVEL
33 
34 //Dependencies
35 #include <string.h>
36 #include "core/net.h"
37 #include "core/bsd_socket.h"
38 #include "core/socket.h"
39 #include "debug.h"
40 
41 //Check TCP/IP stack configuration
42 #if (BSD_SOCKET_SUPPORT == ENABLED)
43 
44 //Common IPv6 addresses
46  {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
47 
49  {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}};
50 
51 
52 /**
53  * @brief Translate error code
54  * @param[in] error Error code to be translated
55  * @return BSD error code
56  **/
57 
59 {
60  int_t ret;
61 
62  //Translate error code
63  switch(error)
64  {
65  case NO_ERROR:
66  ret = 0;
67  break;
68  case ERROR_TIMEOUT:
69  ret = EWOULDBLOCK;
70  break;
72  ret = EINVAL;
73  break;
75  ret = ECONNRESET;
76  break;
78  ret = EISCONN;
79  break;
81  ret = ENOTCONN;
82  break;
84  ret = ESHUTDOWN;
85  break;
87  ret = ECONNREFUSED;
88  break;
89  default:
90  ret = EFAULT;
91  break;
92  }
93 
94  //Return BSD status code
95  return ret;
96 }
97 
98 
99 /**
100  * @brief Create a socket that is bound to a specific transport service provider
101  * @param[in] family Address family
102  * @param[in] type Type specification for the new socket
103  * @param[in] protocol Protocol to be used
104  * @return On success, a file descriptor for the new socket is returned.
105  * On failure, SOCKET_ERROR is returned
106  **/
107 
109 {
110  Socket *sock;
111 
112  //Check address family
113  if(family == AF_INET || family == AF_INET6)
114  {
115  //Create a socket
116  sock = socketOpen(type, protocol);
117  }
118  else if(family == AF_PACKET)
119  {
120  //Create a socket
122  }
123  else
124  {
125  //The address family is not valid
126  return SOCKET_ERROR;
127  }
128 
129  //Failed to create a new socket?
130  if(!sock)
131  {
132  //Report an error
133  return SOCKET_ERROR;
134  }
135 
136  //Return the socket descriptor
137  return sock->descriptor;
138 }
139 
140 
141 /**
142  * @brief Associate a local address with a socket
143  * @param[in] s Descriptor identifying an unbound socket
144  * @param[in] addr Local address to assign to the bound socket
145  * @param[in] addrlen Length in bytes of the address
146  * @return If no error occurs, bind returns SOCKET_SUCCESS.
147  * Otherwise, it returns SOCKET_ERROR
148  **/
149 
150 int_t bind(int_t s, const sockaddr *addr, socklen_t addrlen)
151 {
152  error_t error;
153  uint16_t port;
154  IpAddr ipAddr;
155  Socket *sock;
156 
157  //Make sure the socket descriptor is valid
158  if(s < 0 || s >= SOCKET_MAX_COUNT)
159  {
160  return SOCKET_ERROR;
161  }
162 
163  //Point to the socket structure
164  sock = &socketTable[s];
165 
166  //Check the length of the address
167  if(addrlen < (socklen_t) sizeof(sockaddr))
168  {
169  //Report an error
170  sock->errnoCode = EINVAL;
171  return SOCKET_ERROR;
172  }
173 
174 #if (IPV4_SUPPORT == ENABLED)
175  //IPv4 address?
176  if(addr->sa_family == AF_INET && addrlen >= (socklen_t) sizeof(sockaddr_in))
177  {
178  //Point to the IPv4 address information
179  sockaddr_in *sa = (sockaddr_in *) addr;
180  //Get port number
181  port = ntohs(sa->sin_port);
182 
183  //Copy IPv4 address
184  if(sa->sin_addr.s_addr == INADDR_ANY)
185  {
186  ipAddr.length = 0;
187  ipAddr.ipv4Addr = IPV4_UNSPECIFIED_ADDR;
188  }
189  else
190  {
191  ipAddr.length = sizeof(Ipv4Addr);
192  ipAddr.ipv4Addr = sa->sin_addr.s_addr;
193  }
194  }
195  else
196 #endif
197 #if (IPV6_SUPPORT == ENABLED)
198  //IPv6 address?
199  if(addr->sa_family == AF_INET6 && addrlen >= (socklen_t) sizeof(sockaddr_in6))
200  {
201  //Point to the IPv6 address information
202  sockaddr_in6 *sa = (sockaddr_in6 *) addr;
203  //Get port number
204  port = ntohs(sa->sin6_port);
205 
206  //Copy IPv6 address
208  {
209  ipAddr.length = 0;
210  ipAddr.ipv6Addr = IPV6_UNSPECIFIED_ADDR;
211  }
212  else
213  {
214  ipAddr.length = sizeof(Ipv6Addr);
215  ipv6CopyAddr(&ipAddr.ipv6Addr, sa->sin6_addr.s6_addr);
216  }
217  }
218  else
219 #endif
220  //Invalid address?
221  {
222  //Report an error
223  sock->errnoCode = EINVAL;
224  return SOCKET_ERROR;
225  }
226 
227  //Associate the local address with the socket
228  error = socketBind(sock, &ipAddr, port);
229 
230  //Any error to report?
231  if(error)
232  {
233  sock->errnoCode = socketTranslateErrorCode(error);
234  return SOCKET_ERROR;
235  }
236 
237  //Successful processing
238  return SOCKET_SUCCESS;
239 }
240 
241 
242 /**
243  * @brief Establish a connection to a specified socket
244  * @param[in] s Descriptor identifying an unconnected socket
245  * @param[in] addr Address to which the connection should be established
246  * @param[in] addrlen Length in bytes of the address
247  * @return If no error occurs, connect returns SOCKET_SUCCESS.
248  * Otherwise, it returns SOCKET_ERROR
249  **/
250 
252 {
253  error_t error;
254  uint16_t port;
255  IpAddr ipAddr;
256  Socket *sock;
257 
258  //Make sure the socket descriptor is valid
259  if(s < 0 || s >= SOCKET_MAX_COUNT)
260  {
261  return SOCKET_ERROR;
262  }
263 
264  //Point to the socket structure
265  sock = &socketTable[s];
266 
267  //Check the length of the address
268  if(addrlen < (socklen_t) sizeof(sockaddr))
269  {
270  sock->errnoCode = EINVAL;
271  return SOCKET_ERROR;
272  }
273 
274 #if (IPV4_SUPPORT == ENABLED)
275  //IPv4 address?
276  if(addr->sa_family == AF_INET && addrlen >= (socklen_t) sizeof(sockaddr_in))
277  {
278  //Point to the IPv4 address information
279  sockaddr_in *sa = (sockaddr_in *) addr;
280  //Get port number
281  port = ntohs(sa->sin_port);
282 
283  //Copy IPv4 address
284  if(sa->sin_addr.s_addr == INADDR_ANY)
285  {
286  ipAddr.length = 0;
287  ipAddr.ipv4Addr = IPV4_UNSPECIFIED_ADDR;
288  }
289  else
290  {
291  ipAddr.length = sizeof(Ipv4Addr);
292  ipAddr.ipv4Addr = sa->sin_addr.s_addr;
293  }
294  }
295  else
296 #endif
297 #if (IPV6_SUPPORT == ENABLED)
298  //IPv6 address?
299  if(addr->sa_family == AF_INET6 && addrlen >= (socklen_t) sizeof(sockaddr_in6))
300  {
301  //Point to the IPv6 address information
302  sockaddr_in6 *sa = (sockaddr_in6 *) addr;
303  //Get port number
304  port = ntohs(sa->sin6_port);
305 
306  //Copy IPv6 address
308  {
309  ipAddr.length = 0;
310  ipAddr.ipv6Addr = IPV6_UNSPECIFIED_ADDR;
311  }
312  else
313  {
314  ipAddr.length = sizeof(Ipv6Addr);
315  ipv6CopyAddr(&ipAddr.ipv6Addr, sa->sin6_addr.s6_addr);
316  }
317  }
318  else
319 #endif
320  //Invalid address?
321  {
322  //Report an error
323  sock->errnoCode = EINVAL;
324  return SOCKET_ERROR;
325  }
326 
327  //Establish connection
328  error = socketConnect(sock, &ipAddr, port);
329 
330  //Any error to report?
331  if(error)
332  {
333  sock->errnoCode = socketTranslateErrorCode(error);
334  return SOCKET_ERROR;
335  }
336 
337  //Successful processing
338  return SOCKET_SUCCESS;
339 }
340 
341 
342 /**
343  * @brief Place a socket in the listening state
344  *
345  * Place a socket in a state in which it is listening for an incoming connection
346  *
347  * @param[in] s Descriptor identifying a bound, unconnected socket
348  * @param[in] backlog Maximum length of the queue of pending connections
349  * @return If no error occurs, listen returns SOCKET_SUCCESS.
350  * Otherwise, it returns SOCKET_ERROR
351  **/
352 
353 int_t listen(int_t s, int_t backlog)
354 {
355  error_t error;
356  Socket *sock;
357 
358  //Make sure the socket descriptor is valid
359  if(s < 0 || s >= SOCKET_MAX_COUNT)
360  {
361  return SOCKET_ERROR;
362  }
363 
364  //Point to the socket structure
365  sock = &socketTable[s];
366 
367  //Place the socket in the listening state
368  error = socketListen(sock, backlog);
369 
370  //Any error to report?
371  if(error)
372  {
373  sock->errnoCode = socketTranslateErrorCode(error);
374  return SOCKET_ERROR;
375  }
376 
377  //Successful processing
378  return SOCKET_SUCCESS;
379 }
380 
381 
382 /**
383  * @brief Permit an incoming connection attempt on a socket
384  * @param[in] s Descriptor that identifies a socket in the listening state
385  * @param[out] addr Address of the connecting entity (optional)
386  * @param[in,out] addrlen Length in bytes of the address (optional)
387  * @return If no error occurs, accept returns a descriptor for the new socket.
388  * Otherwise, it returns SOCKET_ERROR
389  **/
390 
392 {
393  uint16_t port;
394  IpAddr ipAddr;
395  Socket *sock;
396  Socket *newSock;
397 
398  //Make sure the socket descriptor is valid
399  if(s < 0 || s >= SOCKET_MAX_COUNT)
400  {
401  return SOCKET_ERROR;
402  }
403 
404  //Point to the socket structure
405  sock = &socketTable[s];
406 
407  //Permit an incoming connection attempt on a socket
408  newSock = socketAccept(sock, &ipAddr, &port);
409 
410  //No connection request is pending in the SYN queue?
411  if(newSock == NULL)
412  {
413  //Report an error
414  sock->errnoCode = EWOULDBLOCK;
415  return SOCKET_ERROR;
416  }
417 
418  //The address is optional
419  if(addr != NULL && addrlen != NULL)
420  {
421 #if (IPV4_SUPPORT == ENABLED)
422  //IPv4 address?
423  if(ipAddr.length == sizeof(Ipv4Addr) && *addrlen >= (socklen_t) sizeof(sockaddr_in))
424  {
425  //Point to the IPv4 address information
426  sockaddr_in *sa = (sockaddr_in *) addr;
427 
428  //Set address family and port number
429  sa->sin_family = AF_INET;
430  sa->sin_port = htons(port);
431  //Copy IPv4 address
432  sa->sin_addr.s_addr = ipAddr.ipv4Addr;
433 
434  //Return the actual length of the address
435  *addrlen = sizeof(sockaddr_in);
436  }
437  else
438 #endif
439 #if (IPV6_SUPPORT == ENABLED)
440  //IPv6 address?
441  if(ipAddr.length == sizeof(Ipv6Addr) && *addrlen >= (socklen_t) sizeof(sockaddr_in6))
442  {
443  //Point to the IPv6 address information
444  sockaddr_in6 *sa = (sockaddr_in6 *) addr;
445 
446  //Set address family and port number
447  sa->sin6_family = AF_INET6;
448  sa->sin6_port = htons(port);
449  //Copy IPv6 address
450  ipv6CopyAddr(sa->sin6_addr.s6_addr, &ipAddr.ipv6Addr);
451 
452  //Return the actual length of the address
453  *addrlen = sizeof(sockaddr_in6);
454  }
455  else
456 #endif
457  //Invalid address?
458  {
459  //Close socket
460  socketClose(newSock);
461  //Report an error
462  sock->errnoCode = EINVAL;
463  return SOCKET_ERROR;
464  }
465  }
466 
467  //Return the descriptor to the new socket
468  return newSock->descriptor;
469 }
470 
471 
472 /**
473  * @brief Send data to a connected socket
474  * @param[in] s Descriptor that identifies a connected socket
475  * @param[in] data Pointer to a buffer containing the data to be transmitted
476  * @param[in] length Number of bytes to be transmitted
477  * @param[in] flags Set of flags that influences the behavior of this function
478  * @return If no error occurs, send returns the total number of bytes sent,
479  * which can be less than the number requested to be sent in the
480  * length parameter. Otherwise, a value of SOCKET_ERROR is returned
481  **/
482 
483 int_t send(int_t s, const void *data, size_t length, int_t flags)
484 {
485  error_t error;
486  size_t written;
487  Socket *sock;
488 
489  //Make sure the socket descriptor is valid
490  if(s < 0 || s >= SOCKET_MAX_COUNT)
491  {
492  return SOCKET_ERROR;
493  }
494 
495  //Point to the socket structure
496  sock = &socketTable[s];
497 
498  //Send data
499  error = socketSend(sock, data, length, &written, flags << 8);
500 
501  //Any error to report?
502  if(error == ERROR_TIMEOUT)
503  {
504  //Check whether some data has been written
505  if(written > 0)
506  {
507  //If a timeout error occurs and some data has been written, the
508  //count of bytes transferred so far is returned...
509  }
510  else
511  {
512  //If no data has been written, a value of SOCKET_ERROR is returned
513  sock->errnoCode = socketTranslateErrorCode(error);
514  return SOCKET_ERROR;
515  }
516  }
517  else if(error != NO_ERROR)
518  {
519  //Otherwise, a value of SOCKET_ERROR is returned
520  sock->errnoCode = socketTranslateErrorCode(error);
521  return SOCKET_ERROR;
522  }
523 
524  //Return the number of bytes transferred so far
525  return written;
526 }
527 
528 
529 /**
530  * @brief Send a datagram to a specific destination
531  * @param[in] s Descriptor that identifies a socket
532  * @param[in] data Pointer to a buffer containing the data to be transmitted
533  * @param[in] length Number of bytes to be transmitted
534  * @param[in] flags Set of flags that influences the behavior of this function
535  * @param[in] addr Destination address
536  * @param[in] addrlen Length in bytes of the destination address
537  * @return If no error occurs, sendto returns the total number of bytes sent,
538  * which can be less than the number requested to be sent in the
539  * length parameter. Otherwise, a value of SOCKET_ERROR is returned
540  **/
541 
542 int_t sendto(int_t s, const void *data, size_t length,
543  int_t flags, const sockaddr *addr, socklen_t addrlen)
544 {
545  error_t error;
546  size_t written;
547  uint16_t port;
548  IpAddr ipAddr;
549  Socket *sock;
550 
551  //Make sure the socket descriptor is valid
552  if(s < 0 || s >= SOCKET_MAX_COUNT)
553  {
554  return SOCKET_ERROR;
555  }
556 
557  //Point to the socket structure
558  sock = &socketTable[s];
559 
560  //Check the length of the address
561  if(addrlen < (socklen_t) sizeof(sockaddr))
562  {
563  //Report an error
564  sock->errnoCode = EINVAL;
565  return SOCKET_ERROR;
566  }
567 
568 #if (IPV4_SUPPORT == ENABLED)
569  //IPv4 address?
570  if(addr->sa_family == AF_INET && addrlen >= (socklen_t) sizeof(sockaddr_in))
571  {
572  //Point to the IPv4 address information
573  sockaddr_in *sa = (sockaddr_in *) addr;
574 
575  //Get port number
576  port = ntohs(sa->sin_port);
577  //Copy IPv4 address
578  ipAddr.length = sizeof(Ipv4Addr);
579  ipAddr.ipv4Addr = sa->sin_addr.s_addr;
580  }
581  else
582 #endif
583 #if (IPV6_SUPPORT == ENABLED)
584  //IPv6 address?
585  if(addr->sa_family == AF_INET6 && addrlen >= (socklen_t) sizeof(sockaddr_in6))
586  {
587  //Point to the IPv6 address information
588  sockaddr_in6 *sa = (sockaddr_in6 *) addr;
589 
590  //Get port number
591  port = ntohs(sa->sin6_port);
592  //Copy IPv6 address
593  ipAddr.length = sizeof(Ipv6Addr);
594  ipv6CopyAddr(&ipAddr.ipv6Addr, sa->sin6_addr.s6_addr);
595  }
596  else
597 #endif
598  //Invalid address?
599  {
600  //Report an error
601  sock->errnoCode = EINVAL;
602  return SOCKET_ERROR;
603  }
604 
605  //Send data
606  error = socketSendTo(sock, &ipAddr, port, data, length, &written, flags << 8);
607 
608  //Any error to report?
609  if(error == ERROR_TIMEOUT)
610  {
611  //Check whether some data has been written
612  if(written > 0)
613  {
614  //If a timeout error occurs and some data has been written, the
615  //count of bytes transferred so far is returned...
616  }
617  else
618  {
619  //If no data has been written, a value of SOCKET_ERROR is returned
620  sock->errnoCode = socketTranslateErrorCode(error);
621  return SOCKET_ERROR;
622  }
623  }
624  else if(error != NO_ERROR)
625  {
626  //Otherwise, a value of SOCKET_ERROR is returned
627  sock->errnoCode = socketTranslateErrorCode(error);
628  return SOCKET_ERROR;
629  }
630 
631  //Return the number of bytes transferred so far
632  return written;
633 }
634 
635 
636 /**
637  * @brief Receive data from a connected socket
638  * @param[in] s Descriptor that identifies a connected socket
639  * @param[out] data Buffer where to store the incoming data
640  * @param[in] size Maximum number of bytes that can be received
641  * @param[in] flags Set of flags that influences the behavior of this function
642  * @return If no error occurs, recv returns the number of bytes received. If the
643  * connection has been gracefully closed, the return value is zero.
644  * Otherwise, a value of SOCKET_ERROR is returned
645  **/
646 
647 int_t recv(int_t s, void *data, size_t size, int_t flags)
648 {
649  error_t error;
650  size_t received;
651  Socket *sock;
652 
653  //Make sure the socket descriptor is valid
654  if(s < 0 || s >= SOCKET_MAX_COUNT)
655  {
656  return SOCKET_ERROR;
657  }
658 
659  //Point to the socket structure
660  sock = &socketTable[s];
661 
662  //Receive data
663  error = socketReceive(sock, data, size, &received, flags << 8);
664 
665  //Any error to report?
666  if(error == ERROR_END_OF_STREAM)
667  {
668  //If the connection has been gracefully closed, the return value is zero
669  return 0;
670  }
671  else if(error != NO_ERROR)
672  {
673  //Otherwise, a value of SOCKET_ERROR is returned
674  sock->errnoCode = socketTranslateErrorCode(error);
675  return SOCKET_ERROR;
676  }
677 
678  //Return the number of bytes received
679  return received;
680 }
681 
682 
683 /**
684  * @brief Receive a datagram
685  * @param[in] s Descriptor that identifies a socket
686  * @param[out] data Buffer where to store the incoming data
687  * @param[in] size Maximum number of bytes that can be received
688  * @param[in] flags Set of flags that influences the behavior of this function
689  * @param[out] addr Source address upon return (optional)
690  * @param[in,out] addrlen Length in bytes of the address (optional)
691  * @return If no error occurs, recvfrom returns the number of bytes received.
692  * If the connection has been gracefully closed, the return value is
693  * zero. Otherwise, a value of SOCKET_ERROR is returned
694  **/
695 
696 int_t recvfrom(int_t s, void *data, size_t size,
697  int_t flags, sockaddr *addr, socklen_t *addrlen)
698 {
699  error_t error;
700  size_t received;
701  uint16_t port;
702  IpAddr ipAddr;
703  Socket *sock;
704 
705  //Make sure the socket descriptor is valid
706  if(s < 0 || s >= SOCKET_MAX_COUNT)
707  {
708  return SOCKET_ERROR;
709  }
710 
711  //Point to the socket structure
712  sock = &socketTable[s];
713 
714  //Receive data
715  error = socketReceiveFrom(sock, &ipAddr, &port, data, size, &received, flags << 8);
716 
717  //Any error to report?
718  if(error == ERROR_END_OF_STREAM)
719  {
720  //If the connection has been gracefully closed, the return value is zero
721  return 0;
722  }
723  else if(error != NO_ERROR)
724  {
725  //Otherwise, a value of SOCKET_ERROR is returned
726  sock->errnoCode = socketTranslateErrorCode(error);
727  return SOCKET_ERROR;
728  }
729 
730  //The address is optional
731  if(addr != NULL && addrlen != NULL)
732  {
733 #if (IPV4_SUPPORT == ENABLED)
734  //IPv4 address?
735  if(ipAddr.length == sizeof(Ipv4Addr) && *addrlen >= (socklen_t) sizeof(sockaddr_in))
736  {
737  //Point to the IPv4 address information
738  sockaddr_in *sa = (sockaddr_in *) addr;
739 
740  //Set address family and port number
741  sa->sin_family = AF_INET;
742  sa->sin_port = htons(port);
743  //Copy IPv4 address
744  sa->sin_addr.s_addr = ipAddr.ipv4Addr;
745 
746  //Return the actual length of the address
747  *addrlen = sizeof(sockaddr_in);
748  }
749  else
750 #endif
751 #if (IPV6_SUPPORT == ENABLED)
752  //IPv6 address?
753  if(ipAddr.length == sizeof(Ipv6Addr) && *addrlen >= (socklen_t) sizeof(sockaddr_in6))
754  {
755  //Point to the IPv6 address information
756  sockaddr_in6 *sa = (sockaddr_in6 *) addr;
757 
758  //Set address family and port number
759  sa->sin6_family = AF_INET6;
760  sa->sin6_port = htons(port);
761  //Copy IPv6 address
762  ipv6CopyAddr(sa->sin6_addr.s6_addr, &ipAddr.ipv6Addr);
763 
764  //Return the actual length of the address
765  *addrlen = sizeof(sockaddr_in6);
766  }
767  else
768 #endif
769  //Invalid address?
770  {
771  //Report an error
772  sock->errnoCode = EINVAL;
773  return SOCKET_ERROR;
774  }
775  }
776 
777  //Return the number of bytes received
778  return received;
779 }
780 
781 
782 /**
783  * @brief Retrieves the local name for a socket
784  * @param[in] s Descriptor identifying a socket
785  * @param[out] addr Address of the socket
786  * @param[in,out] addrlen Length in bytes of the address
787  * @return If no error occurs, getsockname returns SOCKET_SUCCESS
788  * Otherwise, it returns SOCKET_ERROR
789  **/
790 
792 {
793  int_t ret;
794  Socket *sock;
795 
796  //Make sure the socket descriptor is valid
797  if(s < 0 || s >= SOCKET_MAX_COUNT)
798  {
799  return SOCKET_ERROR;
800  }
801 
802  //Point to the socket structure
803  sock = &socketTable[s];
804 
805  //Get exclusive access
807 
808  //Check whether the socket has been bound to an address
809  if(sock->localIpAddr.length != 0)
810  {
811 #if (IPV4_SUPPORT == ENABLED)
812  //IPv4 address?
813  if(sock->localIpAddr.length == sizeof(Ipv4Addr) && *addrlen >= (socklen_t) sizeof(sockaddr_in))
814  {
815  //Point to the IPv4 address information
816  sockaddr_in *sa = (sockaddr_in *) addr;
817 
818  //Set address family and port number
819  sa->sin_family = AF_INET;
820  sa->sin_port = htons(sock->localPort);
821 
822  //Copy IPv4 address
823  sa->sin_addr.s_addr = sock->localIpAddr.ipv4Addr;
824 
825  //Return the actual length of the address
826  *addrlen = sizeof(sockaddr_in);
827  //Successful processing
828  ret = SOCKET_SUCCESS;
829  }
830  else
831 #endif
832 #if (IPV6_SUPPORT == ENABLED)
833  //IPv6 address?
834  if(sock->localIpAddr.length == sizeof(Ipv6Addr) && *addrlen >= (socklen_t) sizeof(sockaddr_in6))
835  {
836  //Point to the IPv6 address information
837  sockaddr_in6 *sa = (sockaddr_in6 *) addr;
838 
839  //Set address family and port number
840  sa->sin6_family = AF_INET6;
841  sa->sin6_port = htons(sock->localPort);
842 
843  //Copy IPv6 address
844  ipv6CopyAddr(sa->sin6_addr.s6_addr, &sock->localIpAddr.ipv6Addr);
845 
846  //Return the actual length of the address
847  *addrlen = sizeof(sockaddr_in6);
848  //Successful processing
849  ret = SOCKET_SUCCESS;
850  }
851  else
852 #endif
853  {
854  //The specified length is not valid
855  sock->errnoCode = EINVAL;
856  ret = SOCKET_ERROR;
857  }
858  }
859  else
860  {
861  //The socket is not bound to any address
862  sock->errnoCode = ENOTCONN;
863  ret = SOCKET_ERROR;
864  }
865 
866  //Release exclusive access
868 
869  //return status code
870  return ret;
871 }
872 
873 
874 /**
875  * @brief Retrieves the address of the peer to which a socket is connected
876  * @param[in] s Descriptor identifying a socket
877  * @param[out] addr Address of the peer
878  * @param[in,out] addrlen Length in bytes of the address
879  * @return If no error occurs, getpeername returns SOCKET_SUCCESS
880  * Otherwise, it returns SOCKET_ERROR
881  **/
882 
884 {
885  int_t ret;
886  Socket *sock;
887 
888  //Make sure the socket descriptor is valid
889  if(s < 0 || s >= SOCKET_MAX_COUNT)
890  {
891  return SOCKET_ERROR;
892  }
893 
894  //Point to the socket structure
895  sock = &socketTable[s];
896 
897  //Get exclusive access
899 
900  //Check whether the socket is connected to a peer
901  if(sock->remoteIpAddr.length != 0)
902  {
903 #if (IPV4_SUPPORT == ENABLED)
904  //IPv4 address?
905  if(sock->remoteIpAddr.length == sizeof(Ipv4Addr) && *addrlen >= (socklen_t) sizeof(sockaddr_in))
906  {
907  //Point to the IPv4 address information
908  sockaddr_in *sa = (sockaddr_in *) addr;
909 
910  //Set address family and port number
911  sa->sin_family = AF_INET;
912  sa->sin_port = htons(sock->remotePort);
913 
914  //Copy IPv4 address
915  sa->sin_addr.s_addr = sock->remoteIpAddr.ipv4Addr;
916 
917  //Return the actual length of the address
918  *addrlen = sizeof(sockaddr_in);
919  //Successful processing
920  ret = SOCKET_SUCCESS;
921  }
922  else
923 #endif
924 #if (IPV6_SUPPORT == ENABLED)
925  //IPv6 address?
926  if(sock->remoteIpAddr.length == sizeof(Ipv6Addr) && *addrlen >= (socklen_t) sizeof(sockaddr_in6))
927  {
928  //Point to the IPv6 address information
929  sockaddr_in6 *sa = (sockaddr_in6 *) addr;
930 
931  //Set address family and port number
932  sa->sin6_family = AF_INET6;
933  sa->sin6_port = htons(sock->remotePort);
934 
935  //Copy IPv6 address
936  ipv6CopyAddr(sa->sin6_addr.s6_addr, &sock->remoteIpAddr.ipv6Addr);
937 
938  //Return the actual length of the address
939  *addrlen = sizeof(sockaddr_in6);
940  //Successful processing
941  ret = SOCKET_SUCCESS;
942  }
943  else
944 #endif
945  {
946  //The specified length is not valid
947  sock->errnoCode = EINVAL;
948  ret = SOCKET_ERROR;
949  }
950  }
951  else
952  {
953  //The socket is not connected to any peer
954  sock->errnoCode = ENOTCONN;
955  ret = SOCKET_ERROR;
956  }
957 
958  //Release exclusive access
960 
961  //return status code
962  return ret;
963 }
964 
965 
966 /**
967  * @brief The setsockopt function sets a socket option
968  * @param[in] s Descriptor that identifies a socket
969  * @param[in] level The level at which the option is defined
970  * @param[in] optname The socket option for which the value is to be set
971  * @param[in] optval A pointer to the buffer in which the value for the requested option is specified
972  * @param[in] optlen The size, in bytes, of the buffer pointed to by the optval parameter
973  * @return If no error occurs, setsockopt returns SOCKET_SUCCESS
974  * Otherwise, it returns SOCKET_ERROR
975  **/
976 
978  const void *optval, socklen_t optlen)
979 {
980  int_t ret;
981  int_t *val;
982  timeval *t;
983  Socket *sock;
984 
985  //Make sure the socket descriptor is valid
986  if(s < 0 || s >= SOCKET_MAX_COUNT)
987  {
988  return SOCKET_ERROR;
989  }
990 
991  //Point to the socket structure
992  sock = &socketTable[s];
993 
994  //Make sure the option is valid
995  if(optval != NULL)
996  {
997  //Level at which the option is defined?
998  if(level == SOL_SOCKET)
999  {
1000  //Check option type
1001  switch(optname)
1002  {
1003  //The socket can be bound to an address which is already in use
1004  case SO_REUSEADDR:
1005  //Ignore the specified option
1006  ret = SOCKET_SUCCESS;
1007  //We are done
1008  break;
1009 
1010  //Allow transmission and receipt of broadcast messages
1011  case SO_BROADCAST:
1012  //Ignore the specified option
1013  ret = SOCKET_SUCCESS;
1014  //We are done
1015  break;
1016 
1017  //Set send buffer size
1018  case SO_SNDBUF:
1019  //Check the length of the option
1020  if(optlen >= (socklen_t) sizeof(int_t))
1021  {
1022  //Cast the option value to the relevant type
1023  val = (int_t *) optval;
1024  //Adjust the size of the send buffer
1025  socketSetTxBufferSize(sock, *val);
1026  //Successful processing
1027  ret = SOCKET_SUCCESS;
1028  }
1029  else
1030  {
1031  //The option length is not valid
1032  sock->errnoCode = EFAULT;
1033  ret = SOCKET_ERROR;
1034  }
1035 
1036  //We are done
1037  break;
1038 
1039  //Set receive buffer size
1040  case SO_RCVBUF:
1041  //Check the length of the option
1042  if(optlen >= (socklen_t) sizeof(int_t))
1043  {
1044  //Cast the option value to the relevant type
1045  val = (int_t *) optval;
1046  //Adjust the size of the receive buffer
1047  socketSetRxBufferSize(sock, *val);
1048  //Successful processing
1049  ret = SOCKET_SUCCESS;
1050  }
1051  else
1052  {
1053  //The option length is not valid
1054  sock->errnoCode = EFAULT;
1055  ret = SOCKET_ERROR;
1056  }
1057 
1058  //We are done
1059  break;
1060 
1061  //Set send timeout or receive timeout
1062  case SO_SNDTIMEO:
1063  case SO_RCVTIMEO:
1064  //Check the length of the option
1065  if(optlen >= (socklen_t) sizeof(timeval))
1066  {
1067  //Cast the option value to the relevant type
1068  t = (timeval *) optval;
1069 
1070  //If the specified value is of zero, I/O operations shall not time out
1071  if(!t->tv_sec && !t->tv_usec)
1073  else
1074  socketSetTimeout(sock, t->tv_sec * 1000 + t->tv_usec / 1000);
1075 
1076  //Successful processing
1077  ret = SOCKET_SUCCESS;
1078  }
1079  else
1080  {
1081  //The option length is not valid
1082  sock->errnoCode = EFAULT;
1083  ret = SOCKET_ERROR;
1084  }
1085 
1086  //We are done
1087  break;
1088 
1089  //Unknown option
1090  default:
1091  //Report an error
1092  sock->errnoCode = ENOPROTOOPT;
1093  ret = SOCKET_ERROR;
1094  break;
1095  }
1096  }
1097  else if(level == IPPROTO_IP)
1098  {
1099  //Check option type
1100  switch(optname)
1101  {
1102  //Time-to-live value
1103  case IP_TTL:
1104  //Check the length of the option
1105  if(optlen >= (socklen_t) sizeof(int_t))
1106  {
1107  //Cast the option value to the relevant type
1108  val = (int_t *) optval;
1109  //Save TTL value
1110  sock->ttl = *val;
1111  //Successful processing
1112  ret = SOCKET_SUCCESS;
1113  }
1114  else
1115  {
1116  //The option length is not valid
1117  sock->errnoCode = EFAULT;
1118  ret = SOCKET_ERROR;
1119  }
1120 
1121  //We are done
1122  break;
1123 
1124  //Time-to-live value for multicast packets
1125  case IP_MULTICAST_TTL:
1126  //Check the length of the option
1127  if(optlen >= (socklen_t) sizeof(int_t))
1128  {
1129  //Cast the option value to the relevant type
1130  val = (int_t *) optval;
1131  //Save TTL value
1132  sock->multicastTtl = *val;
1133  //Successful processing
1134  ret = SOCKET_SUCCESS;
1135  }
1136  else
1137  {
1138  //The option length is not valid
1139  sock->errnoCode = EFAULT;
1140  ret = SOCKET_ERROR;
1141  }
1142 
1143  //We are done
1144  break;
1145 
1146  //Unknown option
1147  default:
1148  //Report an error
1149  sock->errnoCode = ENOPROTOOPT;
1150  ret = SOCKET_ERROR;
1151  break;
1152  }
1153  }
1154  else
1155  {
1156  //The specified level is not valid
1157  sock->errnoCode = EINVAL;
1158  ret = SOCKET_ERROR;
1159  }
1160  }
1161  else
1162  {
1163  //The option is not valid
1164  sock->errnoCode = EFAULT;
1165  ret = SOCKET_ERROR;
1166  }
1167 
1168  //return status code
1169  return ret;
1170 }
1171 
1172 
1173 /**
1174  * @brief The getsockopt function retrieves a socket option
1175  * @param[in] s Descriptor that identifies a socket
1176  * @param[in] level The level at which the option is defined
1177  * @param[in] optname The socket option for which the value is to be retrieved
1178  * @param[out] optval A pointer to the buffer in which the value for the requested option is to be returned
1179  * @param[in,out] optlen The size, in bytes, of the buffer pointed to by the optval parameter
1180  * @return If no error occurs, getsockopt returns SOCKET_SUCCESS
1181  * Otherwise, it returns SOCKET_ERROR
1182  **/
1183 
1185  void *optval, socklen_t *optlen)
1186 {
1187  int_t ret;
1188  int_t *val;
1189  timeval *t;
1190  Socket *sock;
1191 
1192  //Make sure the socket descriptor is valid
1193  if(s < 0 || s >= SOCKET_MAX_COUNT)
1194  {
1195  return SOCKET_ERROR;
1196  }
1197 
1198  //Point to the socket structure
1199  sock = &socketTable[s];
1200 
1201  //Get exclusive access
1203 
1204  //Make sure the option is valid
1205  if(optval != NULL)
1206  {
1207  //Level at which the option is defined?
1208  if(level == SOL_SOCKET)
1209  {
1210  //Check option type
1211  switch(optname)
1212  {
1213 #if (TCP_SUPPORT == ENABLED)
1214  //Get send buffer size
1215  case SO_SNDBUF:
1216  //Check the length of the option
1217  if(*optlen >= (socklen_t) sizeof(int_t))
1218  {
1219  //Cast the option value to the relevant type
1220  val = (int_t *) optval;
1221  //Return the size of the send buffer
1222  *val = sock->txBufferSize;
1223  //Return the actual length of the option
1224  *optlen = sizeof(int_t);
1225  //Successful processing
1226  ret = SOCKET_SUCCESS;
1227  }
1228  else
1229  {
1230  //The option length is not valid
1231  sock->errnoCode = EFAULT;
1232  ret = SOCKET_ERROR;
1233  }
1234 
1235  //We are done
1236  break;
1237 
1238  //Get receive buffer size
1239  case SO_RCVBUF:
1240  //Check the length of the option
1241  if(*optlen >= (socklen_t) sizeof(int_t))
1242  {
1243  //Cast the option value to the relevant type
1244  val = (int_t *) optval;
1245  //Return the size of the receive buffer
1246  *val = sock->rxBufferSize;
1247  //Return the actual length of the option
1248  *optlen = sizeof(int_t);
1249  //Successful processing
1250  ret = SOCKET_SUCCESS;
1251  }
1252  else
1253  {
1254  //The option length is not valid
1255  sock->errnoCode = EFAULT;
1256  ret = SOCKET_ERROR;
1257  }
1258 
1259  //We are done
1260  break;
1261 #endif
1262  //Get send timeout or receive timeout
1263  case SO_SNDTIMEO:
1264  case SO_RCVTIMEO:
1265  //Check the length of the option
1266  if(*optlen >= (socklen_t) sizeof(timeval))
1267  {
1268  //Cast the option value to the relevant type
1269  t = (timeval *) optval;
1270 
1271  //Return the timeout value
1272  if(sock->timeout == INFINITE_DELAY)
1273  {
1274  t->tv_sec = 0;
1275  t->tv_usec = 0;
1276  }
1277  else
1278  {
1279  t->tv_sec = sock->timeout / 1000;
1280  t->tv_usec = (sock->timeout % 1000) * 1000;
1281  }
1282 
1283  //Return the actual length of the option
1284  *optlen = sizeof(timeval);
1285  //Successful processing
1286  ret = SOCKET_SUCCESS;
1287  }
1288  else
1289  {
1290  //The option length is not valid
1291  sock->errnoCode = EFAULT;
1292  ret = SOCKET_ERROR;
1293  }
1294 
1295  //We are done
1296  break;
1297 
1298  //Get error status
1299  case SO_ERROR:
1300  //Check the length of the option
1301  if(*optlen >= (socklen_t) sizeof(int_t))
1302  {
1303  //Cast the option value to the relevant type
1304  val = (int_t *) optval;
1305  //Return the error code
1306  *val = sock->errnoCode;
1307  //Return the actual length of the option
1308  *optlen = sizeof(int_t);
1309 
1310  //Clear error status
1311  sock->errnoCode = 0;
1312 
1313  //Successful processing
1314  ret = SOCKET_SUCCESS;
1315  }
1316  else
1317  {
1318  //The option length is not valid
1319  sock->errnoCode = EFAULT;
1320  ret = SOCKET_ERROR;
1321  }
1322 
1323  //We are done
1324  break;
1325 
1326  //Unknown option
1327  default:
1328  //Report an error
1329  sock->errnoCode = ENOPROTOOPT;
1330  ret = SOCKET_ERROR;
1331  break;
1332  }
1333  }
1334  else if(level == IPPROTO_IP)
1335  {
1336  //Check option type
1337  switch(optname)
1338  {
1339  //Time-to-live value
1340  case IP_TTL:
1341  //Check the length of the option
1342  if(*optlen >= (socklen_t) sizeof(int_t))
1343  {
1344  //Cast the option value to the relevant type
1345  val = (int_t *) optval;
1346  //Return the current TTL value
1347  *val = sock->ttl;
1348  //Return the actual length of the option
1349  *optlen = sizeof(int_t);
1350 
1351  //Successful processing
1352  ret = SOCKET_SUCCESS;
1353  }
1354  else
1355  {
1356  //The option length is not valid
1357  sock->errnoCode = EFAULT;
1358  ret = SOCKET_ERROR;
1359  }
1360 
1361  //We are done
1362  break;
1363 
1364  //Time-to-live value for multicast packets
1365  case IP_MULTICAST_TTL:
1366  //Check the length of the option
1367  if(*optlen >= (socklen_t) sizeof(int_t))
1368  {
1369  //Cast the option value to the relevant type
1370  val = (int_t *) optval;
1371  //Return the current TTL value
1372  *val = sock->ttl;
1373  //Return the actual length of the option
1374  *optlen = sizeof(int_t);
1375 
1376  //Successful processing
1377  ret = SOCKET_SUCCESS;
1378  }
1379  else
1380  {
1381  //The option length is not valid
1382  sock->errnoCode = EFAULT;
1383  ret = SOCKET_ERROR;
1384  }
1385 
1386  //We are done
1387  break;
1388 
1389  //Unknown option
1390  default:
1391  //Report an error
1392  sock->errnoCode = ENOPROTOOPT;
1393  ret = SOCKET_ERROR;
1394  break;
1395  }
1396  }
1397  else
1398  {
1399  //The specified level is not valid
1400  sock->errnoCode = EINVAL;
1401  ret = SOCKET_ERROR;
1402  }
1403  }
1404  else
1405  {
1406  //The option is not valid
1407  sock->errnoCode = EFAULT;
1408  ret = SOCKET_ERROR;
1409  }
1410 
1411  //Release exclusive access
1413 
1414  //return status code
1415  return ret;
1416 }
1417 
1418 
1419 /**
1420  * @brief Control the I/O mode of a socket
1421  * @param[in] s Descriptor that identifies a socket
1422  * @param[in] cmd A command to perform on the socket
1423  * @param[in,out] arg A pointer to a parameter
1424  * @return If no error occurs, setsockopt returns SOCKET_SUCCESS
1425  * Otherwise, it returns SOCKET_ERROR
1426  **/
1427 
1428 int_t ioctlsocket(int_t s, uint32_t cmd, void *arg)
1429 {
1430  int_t ret;
1431  int_t *val;
1432  Socket *sock;
1433 
1434  //Make sure the socket descriptor is valid
1435  if(s < 0 || s >= SOCKET_MAX_COUNT)
1436  {
1437  return SOCKET_ERROR;
1438  }
1439 
1440  //Point to the socket structure
1441  sock = &socketTable[s];
1442 
1443  //Get exclusive access
1445 
1446  //Make sure the parameter is valid
1447  if(arg != NULL)
1448  {
1449  //Check command type
1450  switch(cmd)
1451  {
1452 #if (TCP_SUPPORT == ENABLED)
1453  //Get the number of characters waiting to be read
1454  case FIONREAD:
1455  //Cast the parameter to the relevant type
1456  val = (int_t *) arg;
1457  //Return the number of characters in the receive buffer
1458  *val = sock->rcvUser;
1459  //Successful processing
1460  ret = SOCKET_SUCCESS;
1461  break;
1462 #endif
1463  //Enable or disable non-blocking mode
1464  case FIONBIO:
1465  //Cast the parameter to the relevant type
1466  val = (int_t *) arg;
1467  //Enable blocking or non-blocking operation
1468  sock->timeout = (*val != 0) ? 0 : INFINITE_DELAY;
1469  //Successful processing
1470  ret = SOCKET_SUCCESS;
1471  break;
1472 
1473  //Unknown command?
1474  default:
1475  //Report an error
1476  sock->errnoCode = EINVAL;
1477  ret = SOCKET_ERROR;
1478  break;
1479  }
1480  }
1481  else
1482  {
1483  //The parameter is not valid
1484  sock->errnoCode = EFAULT;
1485  ret = SOCKET_ERROR;
1486  }
1487 
1488  //Release exclusive access
1490 
1491  //return status code
1492  return ret;
1493 }
1494 
1495 
1496 /**
1497  * @brief Perform specific operation
1498  * @param[in] s Descriptor that identifies a socket
1499  * @param[in] cmd A command to perform on the socket
1500  * @param[in,out] arg A pointer to a parameter
1501  * @return If no error occurs, setsockopt returns SOCKET_SUCCESS
1502  * Otherwise, it returns SOCKET_ERROR
1503  **/
1504 
1505 int_t fcntl(int_t s, int_t cmd, void *arg)
1506 {
1507  int_t ret;
1508  int_t *flags;
1509  Socket *sock;
1510 
1511  //Make sure the socket descriptor is valid
1512  if(s < 0 || s >= SOCKET_MAX_COUNT)
1513  {
1514  return SOCKET_ERROR;
1515  }
1516 
1517  //Point to the socket structure
1518  sock = &socketTable[s];
1519 
1520  //Get exclusive access
1522 
1523  //Make sure the parameter is valid
1524  if(arg != NULL)
1525  {
1526  //Check command type
1527  switch(cmd)
1528  {
1529  //Get the file status flags?
1530  case F_GETFL:
1531  //Cast the parameter to the relevant type
1532  flags = (int_t *) arg;
1533  //Check whether non-blocking mode is currently enabled
1534  *flags = (sock->timeout == 0) ? O_NONBLOCK : 0;
1535  //Successful processing
1536  ret = SOCKET_SUCCESS;
1537  break;
1538 
1539  //Set the file status flags?
1540  case F_SETFL:
1541  //Cast the parameter to the relevant type
1542  flags = (int_t *) arg;
1543  //Enable blocking or non-blocking operation
1544  sock->timeout = (*flags & O_NONBLOCK) ? 0 : INFINITE_DELAY;
1545  //Successful processing
1546  ret = SOCKET_SUCCESS;
1547  break;
1548 
1549  //Unknown command?
1550  default:
1551  //Report an error
1552  sock->errnoCode = EINVAL;
1553  ret = SOCKET_ERROR;
1554  break;
1555  }
1556  }
1557  else
1558  {
1559  //Report an error
1560  sock->errnoCode = EFAULT;
1561  ret = SOCKET_ERROR;
1562  }
1563 
1564  //Release exclusive access
1566 
1567  //return status code
1568  return ret;
1569 }
1570 
1571 
1572 /**
1573  * @brief The shutdown function disables sends or receives on a socket
1574  * @param[in] s Descriptor that identifies a socket
1575  * @param[in] how A flag that describes what types of operation will no longer be allowed
1576  * @return If no error occurs, shutdown returns SOCKET_SUCCESS
1577  * Otherwise, it returns SOCKET_ERROR
1578  **/
1579 
1581 {
1582  error_t error;
1583  Socket *sock;
1584 
1585  //Make sure the socket descriptor is valid
1586  if(s < 0 || s >= SOCKET_MAX_COUNT)
1587  {
1588  return SOCKET_ERROR;
1589  }
1590 
1591  //Point to the socket structure
1592  sock = &socketTable[s];
1593 
1594  //Shut down socket
1595  error = socketShutdown(sock, how);
1596 
1597  //Any error to report?
1598  if(error)
1599  {
1600  sock->errnoCode = socketTranslateErrorCode(error);
1601  return SOCKET_ERROR;
1602  }
1603 
1604  //Successful processing
1605  return SOCKET_SUCCESS;
1606 }
1607 
1608 
1609 /**
1610  * @brief The closesocket function closes an existing socket
1611  * @param[in] s Descriptor that identifies a socket
1612  * @return If no error occurs, closesocket returns SOCKET_SUCCESS
1613  * Otherwise, it returns SOCKET_ERROR
1614  **/
1615 
1617 {
1618  Socket *sock;
1619 
1620  //Make sure the socket descriptor is valid
1621  if(s < 0 || s >= SOCKET_MAX_COUNT)
1622  {
1623  return SOCKET_ERROR;
1624  }
1625 
1626  //Point to the socket structure
1627  sock = &socketTable[s];
1628 
1629  //Close socket
1630  socketClose(sock);
1631 
1632  //Successful processing
1633  return SOCKET_SUCCESS;
1634 }
1635 
1636 
1637 /**
1638  * @brief Determine the status of one or more sockets
1639  *
1640  * The select function determines the status of one or more sockets,
1641  * waiting if necessary, to perform synchronous I/O
1642  *
1643  * @param[in] nfds Unused parameter included only for compatibility with Berkeley socket
1644  * @param[in,out] readfds An optional pointer to a set of sockets to be checked for readability
1645  * @param[in,out] writefds An optional pointer to a set of sockets to be checked for writability
1646  * @param[in,out] exceptfds An optional pointer to a set of sockets to be checked for errors
1647  * @param[in] timeout The maximum time for select to wait. Set the timeout
1648  * parameter to null for blocking operations
1649  * @return The select function returns the total number of socket handles that
1650  * are ready and contained in the fd_set structures, zero if the time
1651  * limit expired, or SOCKET_ERROR if an error occurred
1652  **/
1653 
1654 int_t select(int_t nfds, fd_set *readfds, fd_set *writefds,
1655  fd_set *exceptfds, const timeval *timeout)
1656 {
1657  int_t i;
1658  int_t j;
1659  int_t n;
1660  int_t s;
1661  systime_t time;
1662  uint_t eventMask;
1663  uint_t eventFlags;
1664  OsEvent event;
1665  fd_set *fds;
1666 
1667  //Parse all the descriptor sets
1668  for(i = 0; i < 3; i++)
1669  {
1670  //Select the suitable descriptor set
1671  switch(i)
1672  {
1673  case 0:
1674  //Set of sockets to be checked for readability
1675  fds = readfds;
1676  break;
1677  case 1:
1678  //Set of sockets to be checked for writability
1679  fds = writefds;
1680  break;
1681  default:
1682  //Set of sockets to be checked for errors
1683  fds = exceptfds;
1684  break;
1685  }
1686 
1687  //Each descriptor is optional and may be omitted
1688  if(fds != NULL)
1689  {
1690  //Parse the current set of sockets
1691  for(j = 0; j < fds->fd_count; j++)
1692  {
1693  //Invalid socket descriptor?
1694  if(fds->fd_array[j] < 0 || fds->fd_array[j] >= SOCKET_MAX_COUNT)
1695  {
1696  //Report an error
1697  return SOCKET_ERROR;
1698  }
1699  }
1700  }
1701  }
1702 
1703  //Create an event object to get notified of socket events
1704  if(!osCreateEvent(&event))
1705  {
1706  //Failed to create event
1707  return SOCKET_ERROR;
1708  }
1709 
1710  //Parse all the descriptor sets
1711  for(i = 0; i < 3; i++)
1712  {
1713  //Select the suitable descriptor set
1714  switch(i)
1715  {
1716  case 0:
1717  //Set of sockets to be checked for readability
1718  fds = readfds;
1719  eventMask = SOCKET_EVENT_RX_READY;
1720  break;
1721  case 1:
1722  //Set of sockets to be checked for writability
1723  fds = writefds;
1724  eventMask = SOCKET_EVENT_TX_READY;
1725  break;
1726  default:
1727  //Set of sockets to be checked for errors
1728  fds = exceptfds;
1729  eventMask = SOCKET_EVENT_CLOSED;
1730  break;
1731  }
1732 
1733  //Each descriptor is optional and may be omitted
1734  if(fds != NULL)
1735  {
1736  //Parse the current set of sockets
1737  for(j = 0; j < fds->fd_count; j++)
1738  {
1739  //Get the descriptor associated with the current entry
1740  s = fds->fd_array[j];
1741  //Subscribe to the requested events
1742  socketRegisterEvents(&socketTable[s], &event, eventMask);
1743  }
1744  }
1745  }
1746 
1747  //Retrieve timeout value
1748  if(timeout != NULL)
1749  time = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
1750  else
1751  time = INFINITE_DELAY;
1752 
1753  //Block the current task until an event occurs
1754  osWaitForEvent(&event, time);
1755 
1756  //Count the number of events in the signaled state
1757  n = 0;
1758 
1759  //Parse all the descriptor sets
1760  for(i = 0; i < 3; i++)
1761  {
1762  //Select the suitable descriptor set
1763  switch(i)
1764  {
1765  case 0:
1766  //Set of sockets to be checked for readability
1767  fds = readfds;
1768  eventMask = SOCKET_EVENT_RX_READY;
1769  break;
1770  case 1:
1771  //Set of sockets to be checked for writability
1772  fds = writefds;
1773  eventMask = SOCKET_EVENT_TX_READY;
1774  break;
1775  default:
1776  //Set of sockets to be checked for errors
1777  fds = exceptfds;
1778  eventMask = SOCKET_EVENT_CLOSED;
1779  break;
1780  }
1781 
1782  //Each descriptor is optional and may be omitted
1783  if(fds != NULL)
1784  {
1785  //Parse the current set of sockets
1786  for(j = 0; j < fds->fd_count; )
1787  {
1788  //Get the descriptor associated with the current entry
1789  s = fds->fd_array[j];
1790  //Retrieve event flags for the current socket
1791  eventFlags = socketGetEvents(&socketTable[s]);
1792  //Unsubscribe previously registered events
1794 
1795  //Event flag is set?
1796  if(eventFlags & eventMask)
1797  {
1798  //Track the number of events in the signaled state
1799  n++;
1800  //Jump to the next socket descriptor
1801  j++;
1802  }
1803  else
1804  {
1805  //Remove descriptor from the current set
1806  selectFdClr(fds, s);
1807  }
1808  }
1809  }
1810  }
1811 
1812  //Delete event object
1813  osDeleteEvent(&event);
1814  //Return the number of events in the signaled state
1815  return n;
1816 }
1817 
1818 
1819 /**
1820  * @brief Initializes a descriptor set
1821  * @param[in] fds Pointer to a descriptor set
1822  **/
1823 
1825 {
1826  //Reset the descriptor count
1827  fds->fd_count = 0;
1828 }
1829 
1830 
1831 /**
1832  * @brief Add a descriptor to an existing set
1833  * @param[in] fds Pointer to a descriptor set
1834  * @param[in] s Descriptor that identifies the socket to add
1835  **/
1836 
1837 void selectFdSet(fd_set *fds, int_t s)
1838 {
1839  int_t i;
1840 
1841  //Loop through descriptors
1842  for(i = 0; i < fds->fd_count; i++)
1843  {
1844  //The specified descriptor is already set?
1845  if(fds->fd_array[i] == s)
1846  return;
1847  }
1848 
1849  //Ensure the descriptor set is not full
1850  if(i < FD_SETSIZE)
1851  {
1852  //The specified descriptor can be safely added
1853  fds->fd_array[i] = s;
1854  //Adjust the size of the descriptor set
1855  fds->fd_count++;
1856  }
1857 }
1858 
1859 
1860 /**
1861  * @brief Remove a descriptor from an existing set
1862  * @param[in] fds Pointer to a descriptor set
1863  * @param[in] s Descriptor that identifies the socket to remove
1864  **/
1865 
1866 void selectFdClr(fd_set *fds, int_t s)
1867 {
1868  int_t i;
1869  int_t j;
1870 
1871  //Loop through descriptors
1872  for(i = 0; i < fds->fd_count; i++)
1873  {
1874  //Specified descriptor found?
1875  if(fds->fd_array[i] == s)
1876  {
1877  //Adjust the size of the descriptor set
1878  fds->fd_count--;
1879 
1880  //Remove the entry from the descriptor set
1881  for(j = i; j < fds->fd_count; j++)
1882  fds->fd_array[j] = fds->fd_array[j + 1];
1883 
1884  //Return immediately
1885  return;
1886  }
1887  }
1888 }
1889 
1890 
1891 /**
1892  * @brief Check whether a descriptor is set
1893  * @param[in] fds Pointer to a descriptor set
1894  * @param[in] s Descriptor that identifies the socket to test
1895  * @return Nonzero if s is a member of the set. Otherwise, zero
1896  **/
1897 
1899 {
1900  int_t i;
1901 
1902  //Loop through descriptors
1903  for(i = 0; i < fds->fd_count; i++)
1904  {
1905  //Check whether the specified descriptor is set
1906  if(fds->fd_array[i] == s)
1907  return TRUE;
1908  }
1909 
1910  //The specified descriptor is not currently set
1911  return FALSE;
1912 }
1913 
1914 
1915 /**
1916  * @brief Retrieve host address corresponding to a host name
1917  * @param[in] name Name of the host to resolve
1918  * @param[out] info Address of the specified host
1919  * @return If no error occurs, gethostbyname returns 0. Otherwise
1920  * it returns an appropriate error code
1921  **/
1922 
1924 {
1925  error_t error;
1926  IpAddr ipAddr;
1927 
1928  //Check input parameters
1929  if(name == NULL || info == NULL)
1930  return ERROR_INVALID_PARAMETER;
1931 
1932  //Resolve host address
1933  error = getHostByName(NULL, name, &ipAddr, 0);
1934  //Address resolution failed?
1935  if(error)
1936  return error;
1937 
1938 #if (IPV4_SUPPORT == ENABLED)
1939  //IPv4 address?
1940  if(ipAddr.length == sizeof(Ipv4Addr))
1941  {
1942  //Set address family
1943  info->h_addrtype = AF_INET;
1944  //Copy IPv4 address
1945  info->h_length = sizeof(Ipv4Addr);
1946  ipv4CopyAddr(info->h_addr, &ipAddr.ipv4Addr);
1947  }
1948  else
1949 #endif
1950 #if (IPV6_SUPPORT == ENABLED)
1951  //IPv6 address?
1952  if(ipAddr.length == sizeof(Ipv6Addr))
1953  {
1954  //Set address family
1955  info->h_addrtype = AF_INET6;
1956  //Copy IPv6 address
1957  info->h_length = sizeof(Ipv6Addr);
1958  ipv6CopyAddr(info->h_addr, &ipAddr.ipv6Addr);
1959  }
1960  else
1961 #endif
1962  //Invalid address?
1963  {
1964  //Report an error
1965  return ERROR_FAILURE;
1966  }
1967 
1968  //Successful processing
1969  return NO_ERROR;
1970 }
1971 
1972 
1973 /**
1974  * @brief Convert a dot-decimal string into binary data in network byte order
1975  * @param[in] cp NULL-terminated string representing the IPv4 address
1976  * @return Binary data in network byte order
1977  **/
1978 
1980 {
1981 #if (IPV4_SUPPORT == ENABLED)
1982  error_t error;
1983  Ipv4Addr ipv4Addr;
1984 
1985  //Convert a dot-decimal string to a binary IPv4 address
1986  error = ipv4StringToAddr(cp, &ipv4Addr);
1987 
1988  //Check status code
1989  if(error)
1990  {
1991  //The input is invalid
1992  return INADDR_NONE;
1993  }
1994  else
1995  {
1996  //Return the binary representation
1997  return ipv4Addr;
1998  }
1999 #else
2000  //IPv4 is not implemented
2001  return INADDR_NONE;
2002 #endif
2003 }
2004 
2005 
2006 /**
2007  * @brief Convert a dot-decimal string into binary form
2008  * @param[in] cp NULL-terminated string representing the IPv4 address
2009  * @param[out] inp Binary data in network byte order
2010  * @return The function returns non-zero if the address is valid, zero if not
2011  **/
2012 
2013 int_t inet_aton(const char_t *cp, in_addr *inp)
2014 {
2015 #if (IPV4_SUPPORT == ENABLED)
2016  error_t error;
2017  Ipv4Addr ipv4Addr;
2018 
2019  //Convert a dot-decimal string to a binary IPv4 address
2020  error = ipv4StringToAddr(cp, &ipv4Addr);
2021 
2022  //Check status code
2023  if(error)
2024  {
2025  //The input is invalid
2026  return 0;
2027  }
2028  else
2029  {
2030  //Copy the binary representation of the IPv4 address
2031  inp->s_addr = ipv4Addr;
2032  //The conversion succeeded
2033  return 1;
2034  }
2035 #else
2036  //IPv4 is not implemented
2037  return 0;
2038 #endif
2039 }
2040 
2041 
2042 /**
2043  * @brief Convert a binary IPv4 address to dot-decimal notation
2044  * @param[in] in Binary representation of the IPv4 address
2045  * @param[out] cp Pointer to the buffer where to format the string
2046  * @return Pointer to the formatted string
2047  **/
2048 
2050 {
2051 #if (IPV4_SUPPORT == ENABLED)
2052  //Convert the binary IPv4 address to dot-decimal notation
2053  return ipv4AddrToString(in.s_addr, cp);
2054 #else
2055  //Properly terminate the string
2056  cp[0] = '\0';
2057  //Return a pointer to the formatted string
2058  return cp;
2059 #endif
2060 }
2061 
2062 
2063 /**
2064  * @brief Convert an IPv4 or IPv6 address from text to binary form
2065  * @param[in] af Address family
2066  * @param[in] src NULL-terminated string representing the IP address
2067  * @param[out] dst Binary representation of the IP address
2068  * @return The function returns 1 on success. 0 is returned if the address
2069  * is not valid. If the address family is not valid, -1 is returned
2070  **/
2071 
2072 int_t inet_pton(int_t af, const char_t *src, void *dst)
2073 {
2074  error_t error;
2075 
2076 #if (IPV4_SUPPORT == ENABLED)
2077  //IPv4 address?
2078  if(af == AF_INET)
2079  {
2080  Ipv4Addr ipv4Addr;
2081 
2082  //Convert the IPv4 address from text to binary form
2083  error = ipv4StringToAddr(src, &ipv4Addr);
2084 
2085  //Check status code
2086  if(error)
2087  {
2088  //The input is invalid
2089  return 0;
2090  }
2091  else
2092  {
2093  //Copy the binary representation of the IPv4 address
2094  ipv4CopyAddr(dst, &ipv4Addr);
2095  //The conversion succeeded
2096  return 1;
2097  }
2098  }
2099  else
2100 #endif
2101 #if (IPV6_SUPPORT == ENABLED)
2102  //IPv6 address?
2103  if(af == AF_INET6)
2104  {
2105  Ipv6Addr ipv6Addr;
2106 
2107  //Convert the IPv6 address from text to binary form
2108  error = ipv6StringToAddr(src, &ipv6Addr);
2109 
2110  //Check status code
2111  if(error)
2112  {
2113  //The input is invalid
2114  return 0;
2115  }
2116  else
2117  {
2118  //Copy the binary representation of the IPv6 address
2119  ipv6CopyAddr(dst, &ipv6Addr);
2120  //The conversion succeeded
2121  return 1;
2122  }
2123  }
2124  else
2125 #endif
2126  //Invalid address family?
2127  {
2128  //Report an error
2129  return -1;
2130  }
2131 }
2132 
2133 
2134 /**
2135  * @brief Convert an IPv4 or IPv6 address from binary to text
2136  * @param[in] af Address family
2137  * @param[in] src Binary representation of the IP address
2138  * @param[out] dst NULL-terminated string representing the IP address
2139  * @param[in] size Number of bytes available in the buffer
2140  * @return On success, the function returns a pointer to the formatted string.
2141  * NULL is returned if there was an error
2142  **/
2143 
2144 const char_t *inet_ntop(int_t af, const void *src, char_t *dst, socklen_t size)
2145 {
2146 #if (IPV4_SUPPORT == ENABLED)
2147  //IPv4 address?
2148  if(af == AF_INET)
2149  {
2150  Ipv4Addr ipv4Addr;
2151 
2152  //Copy the binary representation of the IPv4 address
2153  ipv4CopyAddr(&ipv4Addr, src);
2154 
2155  //Convert the IPv4 address from text to binary form
2156  return ipv4AddrToString(ipv4Addr, dst);
2157  }
2158  else
2159 #endif
2160 #if (IPV6_SUPPORT == ENABLED)
2161  //IPv6 address?
2162  if(af == AF_INET6)
2163  {
2164  Ipv6Addr ipv6Addr;
2165 
2166  //Copy the binary representation of the IPv6 address
2167  ipv6CopyAddr(&ipv6Addr, src);
2168 
2169  //Convert the IPv6 address from text to binary form
2170  return ipv6AddrToString(&ipv6Addr, dst);
2171  }
2172  else
2173 #endif
2174  //Invalid address family?
2175  {
2176  //Report an error
2177  return NULL;
2178  }
2179 }
2180 
2181 #endif
error_t socketSend(Socket *socket, const void *data, size_t length, size_t *written, uint_t flags)
Send data to a connected socket.
Definition: socket.c:514
#define F_GETFL
Definition: bsd_socket.h:135
char_t * ipv6AddrToString(const Ipv6Addr *ipAddr, char_t *str)
Convert a binary IPv6 address to a string representation.
Definition: ipv6.c:2254
#define htons(value)
Definition: cpu_endian.h:392
uint8_t length
Definition: dtls_misc.h:149
int_t socklen_t
Length type.
Definition: bsd_socket.h:177
int_t inet_pton(int_t af, const char_t *src, void *dst)
Convert an IPv4 or IPv6 address from text to binary form.
Definition: bsd_socket.c:2072
error_t socketBind(Socket *socket, const IpAddr *localIpAddr, uint16_t localPort)
Associate a local address with a socket.
Definition: socket.c:355
#define AF_INET6
Definition: bsd_socket.h:67
uint32_t in_addr_t
IPv4 address.
Definition: bsd_socket.h:184
int_t socketTranslateErrorCode(error_t error)
Translate error code.
Definition: bsd_socket.c:58
#define ENOPROTOOPT
Definition: bsd_socket.h:150
int_t setsockopt(int_t s, int_t level, int_t optname, const void *optval, socklen_t optlen)
The setsockopt function sets a socket option.
Definition: bsd_socket.c:977
#define ESHUTDOWN
Definition: bsd_socket.h:154
signed int int_t
Definition: compiler_port.h:44
IP network address.
Definition: ip.h:71
uint16_t sin_family
Definition: bsd_socket.h:214
int_t shutdown(int_t s, int_t how)
The shutdown function disables sends or receives on a socket.
Definition: bsd_socket.c:1580
struct timeval timeval
Timeout structure.
#define INADDR_ANY
Definition: bsd_socket.h:93
#define EISCONN
Definition: bsd_socket.h:152
#define SOCKET_ERROR
Definition: bsd_socket.h:143
int_t recv(int_t s, void *data, size_t size, int_t flags)
Receive data from a connected socket.
Definition: bsd_socket.c:647
Set of sockets.
Definition: bsd_socket.h:247
#define SO_RCVTIMEO
Definition: bsd_socket.h:117
#define TRUE
Definition: os_port.h:50
void socketClose(Socket *socket)
Close an existing socket.
Definition: socket.c:822
Event object.
#define AF_INET
Definition: bsd_socket.h:66
#define INADDR_NONE
Definition: bsd_socket.h:158
int_t gethostbyname(const char_t *name, hostent *info)
Retrieve host address corresponding to a host name.
Definition: bsd_socket.c:1923
int_t sendto(int_t s, const void *data, size_t length, int_t flags, const sockaddr *addr, socklen_t addrlen)
Send a datagram to a specific destination.
Definition: bsd_socket.c:542
#define SO_SNDBUF
Definition: bsd_socket.h:114
const char_t * inet_ntop(int_t af, const void *src, char_t *dst, socklen_t size)
Convert an IPv4 or IPv6 address from binary to text.
Definition: bsd_socket.c:2144
#define ipv6CompAddr(ipAddr1, ipAddr2)
Definition: ipv6.h:121
int_t selectFdIsSet(fd_set *fds, int_t s)
Check whether a descriptor is set.
Definition: bsd_socket.c:1898
char_t name[]
int_t getsockname(int_t s, sockaddr *addr, socklen_t *addrlen)
Retrieves the local name for a socket.
Definition: bsd_socket.c:791
#define FIONREAD
Definition: bsd_socket.h:131
int_t listen(int_t s, int_t backlog)
Place a socket in the listening state.
Definition: bsd_socket.c:353
#define EINVAL
Definition: bsd_socket.h:149
IPv4 address information.
Definition: bsd_socket.h:212
#define EWOULDBLOCK
Definition: bsd_socket.h:147
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:239
uint_t socketGetEvents(Socket *socket)
Retrieve event flags for a specified socket.
Definition: socket.c:1042
error_t socketSetTxBufferSize(Socket *socket, size_t size)
Specify the size of the send buffer.
Definition: socket.c:244
int_t bind(int_t s, const sockaddr *addr, socklen_t addrlen)
Associate a local address with a socket.
Definition: bsd_socket.c:150
uint8_t h_addr[16]
Definition: bsd_socket.h:273
uint8_t t
Definition: llmnr_common.h:81
#define AF_PACKET
Definition: bsd_socket.h:68
uint8_t level
Definition: tls.h:1702
struct sockaddr_in sockaddr_in
IPv4 address information.
Structure that represents an IPv6 address.
Definition: bsd_socket.h:225
#define SO_RCVBUF
Definition: bsd_socket.h:115
const in6_addr in6addr_loopback
Definition: bsd_socket.c:48
#define FALSE
Definition: os_port.h:46
int32_t tv_sec
Definition: bsd_socket.h:260
error_t socketSetRxBufferSize(Socket *socket, size_t size)
Specify the size of the receive buffer.
Definition: socket.c:278
int_t fd_count
Definition: bsd_socket.h:249
#define IPPROTO_IP
Definition: bsd_socket.h:76
Invalid parameter.
Definition: error.h:47
Socket address.
Definition: bsd_socket.h:191
char_t type
error_t
Error codes.
Definition: error.h:42
const char_t * inet_ntoa(in_addr in, char_t *cp)
Convert a binary IPv4 address to dot-decimal notation.
Definition: bsd_socket.c:2049
IPv6 address information.
Definition: bsd_socket.h:235
error_t socketReceive(Socket *socket, void *data, size_t size, size_t *received, uint_t flags)
Receive data from a connected socket.
Definition: socket.c:609
uint8_t protocol
Structure that represents an IPv4 address.
Definition: bsd_socket.h:202
uint16_t h_length
Definition: bsd_socket.h:272
int_t socket(int_t family, int_t type, int_t protocol)
Create a socket that is bound to a specific transport service provider.
Definition: bsd_socket.c:108
Generic error code.
Definition: error.h:45
void selectFdZero(fd_set *fds)
Initializes a descriptor set.
Definition: bsd_socket.c:1824
struct sockaddr_in6 sockaddr_in6
IPv6 address information.
void osDeleteEvent(OsEvent *event)
Delete an event object.
#define ENOTCONN
Definition: bsd_socket.h:153
#define SO_REUSEADDR
Definition: bsd_socket.h:109
#define SO_BROADCAST
Definition: bsd_socket.h:112
BSD socket API.
error_t socketReceiveFrom(Socket *socket, IpAddr *srcIpAddr, uint16_t *srcPort, void *data, size_t size, size_t *received, uint_t flags)
Receive a datagram from a connectionless socket.
Definition: socket.c:629
int_t recvfrom(int_t s, void *data, size_t size, int_t flags, sockaddr *addr, socklen_t *addrlen)
Receive a datagram.
Definition: bsd_socket.c:696
#define IP_MULTICAST_TTL
Definition: bsd_socket.h:125
error_t getHostByName(NetInterface *interface, const char_t *name, IpAddr *ipAddr, uint_t flags)
Resolve a host name into an IP address.
Definition: socket.c:1078
int_t inet_aton(const char_t *cp, in_addr *inp)
Convert a dot-decimal string into binary form.
Definition: bsd_socket.c:2013
#define SOCKET_SUCCESS
Definition: bsd_socket.h:142
OsMutex netMutex
Definition: net.c:75
error_t socketConnect(Socket *socket, const IpAddr *remoteIpAddr, uint16_t remotePort)
Establish a connection to a specified socket.
Definition: socket.c:381
const Ipv6Addr IPV6_UNSPECIFIED_ADDR
Definition: ipv6.c:67
__start_packed struct @179 Ipv6Addr
IPv6 network address.
error_t socketShutdown(Socket *socket, uint_t how)
Disable reception, transmission, or both.
Definition: socket.c:785
int_t fd_array[FD_SETSIZE]
Definition: bsd_socket.h:250
Socket * socketOpen(uint_t type, uint_t protocol)
Create a socket (UDP or TCP)
Definition: socket.c:95
#define SO_SNDTIMEO
Definition: bsd_socket.h:116
int_t connect(int_t s, const sockaddr *addr, socklen_t addrlen)
Establish a connection to a specified socket.
Definition: bsd_socket.c:251
in_addr_t inet_addr(const char_t *cp)
Convert a dot-decimal string into binary data in network byte order.
Definition: bsd_socket.c:1979
uint16_t sin6_family
Definition: bsd_socket.h:237
int32_t tv_usec
Definition: bsd_socket.h:261
Socket socketTable[SOCKET_MAX_COUNT]
Definition: socket.c:49
void socketUnregisterEvents(Socket *socket)
Unsubscribe previously registered events.
Definition: socket.c:1019
Socket * socketAccept(Socket *socket, IpAddr *clientIpAddr, uint16_t *clientPort)
Permit an incoming connection attempt on a socket.
Definition: socket.c:481
int_t ioctlsocket(int_t s, uint32_t cmd, void *arg)
Control the I/O mode of a socket.
Definition: bsd_socket.c:1428
uint16_t port
Definition: dns_common.h:223
#define ntohs(value)
Definition: cpu_endian.h:398
in_addr_t s_addr
Definition: bsd_socket.h:204
uint8_t flags
Definition: tcp.h:314
#define EFAULT
Definition: bsd_socket.h:148
char char_t
Definition: compiler_port.h:43
void socketRegisterEvents(Socket *socket, OsEvent *event, uint_t eventMask)
Subscribe to the specified socket events.
Definition: socket.c:968
Information about a given host.
Definition: bsd_socket.h:269
#define F_SETFL
Definition: bsd_socket.h:136
uint32_t time
#define ipv6CopyAddr(destIpAddr, srcIpAddr)
Definition: ipv6.h:117
#define FIONBIO
Definition: bsd_socket.h:132
uint8_t n
bool_t osWaitForEvent(OsEvent *event, systime_t timeout)
Wait until the specified event is in the signaled state.
Timeout structure.
Definition: bsd_socket.h:258
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
uint16_t sin_port
Definition: bsd_socket.h:215
uint16_t sin6_port
Definition: bsd_socket.h:238
#define ECONNREFUSED
Definition: bsd_socket.h:155
#define Socket
Definition: socket.h:36
int_t getpeername(int_t s, sockaddr *addr, socklen_t *addrlen)
Retrieves the address of the peer to which a socket is connected.
Definition: bsd_socket.c:883
bool_t osCreateEvent(OsEvent *event)
Create an event object.
#define SOL_SOCKET
Definition: bsd_socket.h:90
#define ECONNRESET
Definition: bsd_socket.h:151
uint8_t s
in_addr sin_addr
Definition: bsd_socket.h:216
Socket API.
error_t socketSendTo(Socket *socket, const IpAddr *destIpAddr, uint16_t destPort, const void *data, size_t length, size_t *written, uint_t flags)
Send a datagram to a specific destination.
Definition: socket.c:535
int_t getsockopt(int_t s, int_t level, int_t optname, void *optval, socklen_t *optlen)
The getsockopt function retrieves a socket option.
Definition: bsd_socket.c:1184
#define ipv4CopyAddr(destIpAddr, srcIpAddr)
Definition: ipv4.h:142
error_t ipv4StringToAddr(const char_t *str, Ipv4Addr *ipAddr)
Convert a dot-decimal string to a binary IPv4 address.
Definition: ipv4.c:1379
error_t ipv6StringToAddr(const char_t *str, Ipv6Addr *ipAddr)
Convert a string representation of an IPv6 address to a binary IPv6 address.
Definition: ipv6.c:2114
void selectFdSet(fd_set *fds, int_t s)
Add a descriptor to an existing set.
Definition: bsd_socket.c:1837
#define O_NONBLOCK
Definition: bsd_socket.h:139
Ipv4Addr addr
Definition: nbns_common.h:121
void selectFdClr(fd_set *fds, int_t s)
Remove a descriptor from an existing set.
Definition: bsd_socket.c:1866
#define IP_TTL
Definition: bsd_socket.h:124
unsigned int uint_t
Definition: compiler_port.h:45
TCP/IP stack core.
uint8_t data[]
Definition: dtls_misc.h:176
int_t fcntl(int_t s, int_t cmd, void *arg)
Perform specific operation.
Definition: bsd_socket.c:1505
char_t * ipv4AddrToString(Ipv4Addr ipAddr, char_t *str)
Convert a binary IPv4 address to dot-decimal notation.
Definition: ipv4.c:1466
const in6_addr in6addr_any
Definition: bsd_socket.c:45
#define SOCKET_MAX_COUNT
Definition: socket.h:45
#define FD_SETSIZE
Definition: bsd_socket.h:161
int_t accept(int_t s, sockaddr *addr, socklen_t *addrlen)
Permit an incoming connection attempt on a socket.
Definition: bsd_socket.c:391
error_t socketSetTimeout(Socket *socket, systime_t timeout)
Set timeout value for blocking operations.
Definition: socket.c:219
int_t send(int_t s, const void *data, size_t length, int_t flags)
Send data to a connected socket.
Definition: bsd_socket.c:483
int_t select(int_t nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const timeval *timeout)
Determine the status of one or more sockets.
Definition: bsd_socket.c:1654
uint32_t systime_t
Definition: compiler_port.h:46
uint8_t ipAddr[4]
Definition: mib_common.h:187
in6_addr sin6_addr
Definition: bsd_socket.h:239
Success.
Definition: error.h:44
Debugging facilities.
uint8_t s6_addr[16]
Definition: bsd_socket.h:227
#define INFINITE_DELAY
Definition: os_port.h:74
#define IPV4_UNSPECIFIED_ADDR
Definition: ipv4.h:104
int_t closesocket(int_t s)
The closesocket function closes an existing socket.
Definition: bsd_socket.c:1616
uint16_t h_addrtype
Definition: bsd_socket.h:271
#define SO_ERROR
Definition: bsd_socket.h:118
error_t socketListen(Socket *socket, uint_t backlog)
Place a socket in the listening state.
Definition: socket.c:444