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