Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
FreeRTOSTCPSocket.cxx
Go to the documentation of this file.
1
35#include <fcntl.h>
36#include <unistd.h>
37#include <sys/socket.h>
38#include <netinet/in.h>
39#include <netinet/tcp.h>
40#include <stdio.h>
41
42// FreeRTOS
43#include "FreeRTOS.h"
44#include "task.h"
45
46// FreeRTOSPTCP includes
47#include "FreeRTOS_IP.h"
48#include "FreeRTOS_Sockets.h"
49
50#include "FreeRTOSTCPSocket.hxx"
51#include "FreeRTOSTCP.hxx"
52
53static FreeRTOSTCPSocket *FreeRTOSTCPSockets[MAX_SOCKETS];
54
55/*
56 * FreeRTOSTCPSocket::socket()
57 */
58int FreeRTOSTCPSocket::socket(int domain, int type, int protocol)
59{
60 FreeRTOSTCPSocket *new_socket = new FreeRTOSTCPSocket();
61 if (new_socket == nullptr)
62 {
63 errno = ENOMEM;
64 return -1;
65 }
66
67 mutex.lock();
68 int fd = fd_alloc();
69 mutex.unlock();
70 if (fd < 0)
71 {
72 delete new_socket;
73 errno = EMFILE;
74 return -1;
75 }
76
77 switch (domain)
78 {
79 case AF_INET:
80 domain = FREERTOS_AF_INET;
81 break;
82 default:
83 fd_free(fd);
84 errno = EAFNOSUPPORT;
85 return -1;
86 }
87
88 switch (type)
89 {
90 case SOCK_STREAM:
91 type = FREERTOS_SOCK_STREAM;
92 break;
93 case SOCK_DGRAM:
94 type = FREERTOS_SOCK_DGRAM;
95 break;
96 default:
97 fd_free(fd);
98 errno = EINVAL;
99 return -1;
100 }
101
102 switch (protocol)
103 {
104 case 0:
105 break;
106 case IPPROTO_TCP:
107 protocol = FREERTOS_IPPROTO_TCP;
108 break;
109 case IPPROTO_UDP:
110 protocol = FREERTOS_IPPROTO_UDP;
111 break;
112 default:
113 fd_free(fd);
114 errno = EINVAL;
115 return -1;
116 }
117
118 Socket_t sd = FreeRTOS_socket(domain, type, protocol);
119
120 if (sd == FREERTOS_INVALID_SOCKET)
121 {
122 // unable to allocate socket due to no memory
123 errno = ENOMEM;
124 fd_free(fd);
125 return -1;
126 }
127
128 File *file = file_lookup(fd);
129
130 file->dev = new_socket;
131 file->flags = O_RDWR;
132 file->priv = new_socket;
133
134 new_socket->sd = sd;
135 new_socket->references_ = 1;
136
137 portENTER_CRITICAL();
138 for (int i = 1; i < MAX_SOCKETS; ++i)
139 {
140 if (FreeRTOSTCPSockets[i] == NULL)
141 {
142 FreeRTOSTCPSockets[i] = new_socket;
143 break;
144 }
145 }
146 portEXIT_CRITICAL();
147
148 return fd;
149}
150
151/*
152 * FreeRTOSTCPSocket::bind()
153 */
155 int socket, const struct sockaddr *address, socklen_t address_len)
156{
157 File *f = file_lookup(socket);
158 if (!f)
159 {
160 errno = EBADF;
161 return -1;
162 }
163
164 FreeRTOSTCPSocket *s = static_cast<FreeRTOSTCPSocket *>(f->priv);
165 if (!S_ISSOCK(s->mode_))
166 {
167 errno = ENOTSOCK;
168 return -1;
169 }
170
171 struct freertos_sockaddr fr_address;
172 fr_address.sin_len = sizeof(fr_address);
173
174 switch (address->sa_family)
175 {
176 case AF_INET:
177 fr_address.sin_family = FREERTOS_AF_INET;
178 break;
179 default:
180 errno = EINVAL;
181 return -1;
182 }
183
184 struct sockaddr_in *sin = (struct sockaddr_in *)(address);
185 fr_address.sin_addr = sin->sin_addr.s_addr;
186 fr_address.sin_port = sin->sin_port;
187
188 int result = FreeRTOS_bind(s->sd, &fr_address, sizeof(fr_address));
189
190 if (result < 0)
191 {
192 switch (result)
193 {
194 case -FREERTOS_EINVAL:
195 errno = EINVAL;
196 break;
197 default:
198 HASSERT(0);
199 break;
200 }
201 return -1;
202 }
203
204 return result;
205}
206
207/*
208 * FreeRTOSTCPSocket::listen()
209 */
211{
212 File *f = file_lookup(socket);
213 if (!f)
214 {
215 errno = EBADF;
216 return -1;
217 }
218
219 FreeRTOSTCPSocket *s = static_cast<FreeRTOSTCPSocket *>(f->priv);
220 if (!S_ISSOCK(s->mode_))
221 {
222 errno = ENOTSOCK;
223 return -1;
224 }
225
226 int result = FreeRTOS_listen(s->sd, backlog);
227
228 if (result < 0)
229 {
230 switch (result)
231 {
232 case -pdFREERTOS_ERRNO_EOPNOTSUPP:
233 errno = EBADF;
234 break;
235 default:
236 HASSERT(0);
237 break;
238 }
239 return -1;
240 }
241 s->readActive = false;
242 s->listenActive = true;
243
244 return result;
245}
246
247/*
248 * FreeRTOSTCPSocket::accept()
249 */
251 int socket, struct sockaddr *address, socklen_t *address_len)
252{
253 int result;
254 struct sockaddr_in *sin = (struct sockaddr_in *)(address);
255 File *f = file_lookup(socket);
256 if (!f)
257 {
258 errno = EBADF;
259 return -1;
260 }
261
262 FreeRTOSTCPSocket *s = static_cast<FreeRTOSTCPSocket *>(f->priv);
263 if (!S_ISSOCK(s->mode_))
264 {
265 errno = ENOTSOCK;
266 return -1;
267 }
268
269 if (!s->listenActive)
270 {
271 errno = EINVAL;
272 return -1;
273 }
274
275 freertos_sockaddr fr_address;
276 socklen_t fr_address_len = sizeof(fr_address);
277
278 Socket_t sd = FreeRTOS_accept(s->sd, &fr_address, &fr_address_len);
279
280 if (address && address_len && (*address_len >= sizeof(sockaddr_in)))
281 {
282 // copy the address across and set the address family
283 sin->sin_port = fr_address.sin_port;
284 sin->sin_addr.s_addr = fr_address.sin_addr;
285 sin->sin_family = AF_INET;
286 *address_len = sizeof(struct sockaddr_in);
287 }
288
289 if (sd == NULL)
290 {
291 // no queued connections
292 errno = EAGAIN;
293 return -1;
294 }
295 if (sd == FREERTOS_INVALID_SOCKET)
296 {
297 // bad socket or not listening
298 errno = EBADF;
299 return -1;
300 }
301
302 // for compatibility reset any timeout values inherited from listening
303 // socket
304 const TickType_t timeout = portMAX_DELAY;
305 result = FreeRTOS_setsockopt(sd, 0, FREERTOS_SO_RCVTIMEO, &timeout, 0);
306 if (result != 0)
307 {
308 // error detected
309 }
310 result = FreeRTOS_setsockopt(sd, 0, FREERTOS_SO_SNDTIMEO, &timeout, 0);
311 if (result != 0)
312 {
313 // error detected
314 }
315
316 // set listening socket state
317 s->readActive = false;
318
319 return alloc_instance(sd);
320}
321
322/*
323 * FreeRTOSTCPSocket::connect()
324 */
326 int socket, const struct sockaddr *address, socklen_t address_len)
327{
328 const struct sockaddr_in *sin = (const struct sockaddr_in *)(address);
329 File *f = file_lookup(socket);
330 if (!f)
331 {
332 errno = EBADF;
333 return -1;
334 }
335
336 FreeRTOSTCPSocket *s = static_cast<FreeRTOSTCPSocket *>(f->priv);
337 if (!S_ISSOCK(s->mode_))
338 {
339 errno = ENOTSOCK;
340 return -1;
341 }
342
343 struct freertos_sockaddr fr_address;
344 socklen_t fr_address_len = sizeof(fr_address);
345 fr_address.sin_len = sizeof(fr_address);
346
347 switch (sin->sin_family)
348 {
349 case AF_INET:
350 fr_address.sin_family = FREERTOS_AF_INET;
351 break;
352 default:
353 errno = EINVAL;
354 return -1;
355 }
356
357 fr_address.sin_addr = sin->sin_addr.s_addr;
358 fr_address.sin_port = sin->sin_port;
359
360 int result = FreeRTOS_connect(s->sd, &fr_address, fr_address_len);
361
362 if (result)
363 {
364 switch (result)
365 {
366 case -pdFREERTOS_ERRNO_EBADF:
367 errno = EBADF;
368 break;
369 case -pdFREERTOS_ERRNO_EISCONN:
370 errno = EALREADY;
371 break;
372 case -pdFREERTOS_ERRNO_EINPROGRESS:
373 case -pdFREERTOS_ERRNO_EAGAIN:
374 errno = EAGAIN;
375 break;
376 case -FREERTOS_EWOULDBLOCK:
377 errno = EWOULDBLOCK;
378 break;
379 case -pdFREERTOS_ERRNO_ETIMEDOUT:
380 errno = ETIMEDOUT;
381 break;
382 default:
383 HASSERT(0);
384 break;
385 }
386 return -1;
387 }
388 return result;
389}
390
391/*
392 * FreeRTOSTCPSocket::recv()
393 */
395 int socket, void *buffer, size_t length, int flags)
396{
397 /* flags are not supported in FreeRTOSTCPSocket */
398 HASSERT(flags == 0);
399
400 File *f = file_lookup(socket);
401 if (!f)
402 {
403 errno = EBADF;
404 return -1;
405 }
406
407 FreeRTOSTCPSocket *s = static_cast<FreeRTOSTCPSocket *>(f->priv);
408 if (!S_ISSOCK(s->mode_))
409 {
410 errno = ENOTSOCK;
411 return -1;
412 }
413
414 int result = FreeRTOS_recv(s->sd, buffer, length, flags);
415
416 if (result == 0)
417 {
418 s->readActive = false;
419 errno = EAGAIN;
420 return -1;
421 }
422
423 if (result < 0)
424 {
425 switch (result)
426 {
427 case -pdFREERTOS_ERRNO_ENOMEM:
428 errno = ENOMEM;
429 break;
430 case -pdFREERTOS_ERRNO_ENOTCONN:
431 errno = ENOTCONN;
432 break;
433 case -pdFREERTOS_ERRNO_EINTR:
434 errno = EINTR;
435 break;
436 case -pdFREERTOS_ERRNO_EINVAL:
437 errno = EINVAL;
438 break;
439 default:
440 HASSERT(0);
441 break;
442 }
443 return -1;
444 }
445 if ((size_t)result < length)
446 {
447 s->readActive = false;
448 }
449 else
450 {
451 s->readActive = true;
452 }
453
454 return result;
455}
456
457/*
458 * FreeRTOSTCPSocket::send()
459 */
461 int socket, const void *buffer, size_t length, int flags)
462{
463 /* flags are not supported in FreeRTOSTCPSocket */
464 HASSERT(flags == 0);
465
466 File *f = file_lookup(socket);
467 if (!f)
468 {
469 errno = EBADF;
470 return -1;
471 }
472
473 FreeRTOSTCPSocket *s = static_cast<FreeRTOSTCPSocket *>(f->priv);
474 if (!S_ISSOCK(s->mode_))
475 {
476 errno = ENOTSOCK;
477 return -1;
478 }
479
480 int result = FreeRTOS_send(s->sd, buffer, length, flags);
481
482 if (result < 0)
483 {
484 switch (result)
485 {
486 case -pdFREERTOS_ERRNO_ENOTCONN:
487 errno = ENOTCONN;
488 break;
489 case -pdFREERTOS_ERRNO_ENOMEM:
490 errno = ENOMEM;
491 break;
492 case -pdFREERTOS_ERRNO_EINVAL:
493 errno = EINVAL;
494 break;
495 case -pdFREERTOS_ERRNO_ENOSPC:
496 errno = ENOSPC;
497 break;
498 default:
499 HASSERT(0);
500 break;
501 }
502 return -1;
503 }
504 if ((size_t)result < length)
505 {
506 s->writeActive = false;
507 }
508 else
509 {
510 s->writeActive = true;
511 }
512
513 return result;
514}
515
516/*
517 * FreeRTOSTCPSocket::setsockopt()
518 */
519int FreeRTOSTCPSocket::setsockopt(int socket, int level, int option_name,
520 const void *option_value, socklen_t option_len)
521{
522 File *f = file_lookup(socket);
523 if (!f)
524 {
525 errno = EBADF;
526 return -1;
527 }
528
529 FreeRTOSTCPSocket *s = static_cast<FreeRTOSTCPSocket *>(f->priv);
530 if (!S_ISSOCK(s->mode_))
531 {
532 errno = ENOTSOCK;
533 return -1;
534 }
535
536 int result;
537 TickType_t timeout;
538 const struct timeval *tm;
539
540 switch (level)
541 {
542 default:
543 errno = EINVAL;
544 return -1;
545 case SOL_SOCKET:
546 switch (option_name)
547 {
548 case SO_REUSEADDR:
549 // ignore as FreeRTOS semantics different from BSD
550 return 0;
551 case SO_RCVTIMEO:
552 tm = static_cast<const struct timeval *>(option_value);
553 timeout = pdMS_TO_TICKS(
554 (tm->tv_sec * 1000000 + tm->tv_usec) / 1000);
555 result = FreeRTOS_setsockopt(
556 s->sd, 0, FREERTOS_SO_RCVTIMEO, &timeout, 0);
557 if (result == -FREERTOS_EINVAL)
558 {
559 errno = EINVAL;
560 return -1;
561 }
562 return 0;
563 case SO_SNDTIMEO:
564 tm = static_cast<const struct timeval *>(option_value);
565 timeout = pdMS_TO_TICKS(
566 (tm->tv_sec * 1000000 + tm->tv_usec) / 1000);
567 result = FreeRTOS_setsockopt(
568 s->sd, 0, FREERTOS_SO_SNDTIMEO, &timeout, 0);
569 if (result == -FREERTOS_EINVAL)
570 {
571 errno = EINVAL;
572 return -1;
573 }
574 return 0;
575 default:
576 errno = EINVAL;
577 return -1;
578 }
579 break;
580 case IPPROTO_TCP:
581 switch (option_name)
582 {
583 case TCP_NODELAY:
584 // not implemented, return no error
585 return 0;
586 default:
587 errno = EINVAL;
588 return -1;
589 }
590 }
591
592 result = FreeRTOS_setsockopt(
593 s->sd, level, option_name, option_value, option_len);
594
595 if (result < 0)
596 {
597 switch (result)
598 {
599 case -FREERTOS_EINVAL:
600 errno = EINVAL;
601 break;
602 default:
603 HASSERT(0);
604 break;
605 }
606 return -1;
607 }
608
609 return result;
610}
611
612/*
613 * FreeRTOSTCPSocket::getsockopt()
614 */
615int FreeRTOSTCPSocket::getsockopt(int socket, int level, int option_name,
616 void *option_value, socklen_t *option_len)
617{
618 File *f = file_lookup(socket);
619 if (!f)
620 {
621 errno = EBADF;
622 return -1;
623 }
624
625 FreeRTOSTCPSocket *s = static_cast<FreeRTOSTCPSocket *>(f->priv);
626 if (!S_ISSOCK(s->mode_))
627 {
628 errno = ENOTSOCK;
629 return -1;
630 }
631
632 return 0;
633
634 // FreeRTOSTCPSocket does not support getsockopt
635 errno = EINVAL;
636 return -1;
637}
638
639/*
640 * FreeRTOSTCPSocket::close()
641 */
643{
644 FreeRTOSTCPSocket *s = static_cast<FreeRTOSTCPSocket *>(file->priv);
645
646 mutex.lock();
647 if (--references_ == 0)
648 {
649 mutex.unlock();
650 /* request that the socket be closed */
652 }
653 else
654 {
655 mutex.unlock();
656 }
657
658 return 0;
659}
660
667bool FreeRTOSTCPSocket::select(File *file, int mode)
668{
669 FreeRTOSTCPSocket *s = static_cast<FreeRTOSTCPSocket *>(file->priv);
670 bool retval = false;
671
672 switch (mode)
673 {
674 case FREAD:
675 portENTER_CRITICAL();
676 if (readActive)
677 {
678 retval = true;
679 portEXIT_CRITICAL();
680 }
681 else
682 {
684 portEXIT_CRITICAL();
686 }
687 break;
688 case FWRITE:
689 portENTER_CRITICAL();
690 HASSERT(listenActive == false);
691 if (writeActive)
692 {
693 retval = true;
694 portEXIT_CRITICAL();
695 }
696 else
697 {
699 portEXIT_CRITICAL();
701 }
702 break;
703 default:
704 case 0:
705 /* we don't support any exceptions */
706 break;
707 }
708 return retval;
709}
710
711/*
712 * FreeRTOSTCPSocket::get_sd_by_index()
713 */
714
716{
717 if ((inx < 0) || (inx > MAX_SOCKETS))
718 {
719 HASSERT(0);
720 }
721 return FreeRTOSTCPSockets[inx];
722}
723
724/*
725 * FreeRTOSTCPSocket::alloc_instance()
726 */
728{
729 FreeRTOSTCPSocket *new_socket = new FreeRTOSTCPSocket();
730
731 mutex.lock();
732 int fd = fd_alloc();
733 mutex.unlock();
734 if (fd < 0)
735 {
736 errno = EMFILE;
737 return -1;
738 }
739
740 File *file = file_lookup(fd);
741
742 file->dev = new_socket;
743 file->flags = O_RDWR;
744 file->priv = new_socket;
745
746 new_socket->sd = sd;
747 new_socket->references_ = 1;
748
749 portENTER_CRITICAL();
750 for (int i = 1; i < MAX_SOCKETS; ++i)
751 {
752 if (FreeRTOSTCPSockets[i] == nullptr)
753 {
754 FreeRTOSTCPSockets[i] = new_socket;
755 break;
756 }
757 }
758 portEXIT_CRITICAL();
759
760 return fd;
761}
762/*
763 * FreeRTOSTCPSocket::get_instance_from_sd()
764 */
766{
767 for (int i = 0; i < MAX_SOCKETS; ++i)
768 {
769 if (sd == FreeRTOSTCPSockets[i]->sd)
770 {
771 return FreeRTOSTCPSockets[i];
772 }
773 }
774 HASSERT(0);
775 return nullptr;
776}
777
778/*
779 * FreeRTOSTCPSocket::remove_instance_from_sd()
780 */
782{
783 for (int i = 0; i < MAX_SOCKETS; ++i)
784 {
785 if (sd == FreeRTOSTCPSockets[i]->sd)
786 {
787 FreeRTOSTCPSockets[i] = NULL;
788 return;
789 }
790 }
791 HASSERT(0);
792}
793
794/*
795 * FreeRTOSTCPSocket::fcntl()
796 */
797int FreeRTOSTCPSocket::fcntl(File *file, int cmd, unsigned long data)
798{
799 FreeRTOSTCPSocket *s = static_cast<FreeRTOSTCPSocket *>(file->priv);
800 if (!S_ISSOCK(s->mode_))
801 {
802 errno = ENOTSOCK;
803 return -1;
804 }
805
806 switch (cmd)
807 {
808 case F_SETFL:
809 if (data & O_NONBLOCK)
810 {
811 // translate set non blocking into zero Recv and Send timeouts
812 static const TickType_t timeout = 0;
813 FreeRTOS_setsockopt(sd, 0, FREERTOS_SO_RCVTIMEO,
814 (void *)&timeout, sizeof(timeout));
815 FreeRTOS_setsockopt(sd, 0, FREERTOS_SO_SNDTIMEO,
816 (void *)&timeout, sizeof(timeout));
817 }
818 return 0;
819 case F_GETFL:
820 return 0;
821 default:
822 {
823 return -EINVAL;
824 }
825 }
826}
827
828extern "C" {
841int socket(int domain, int type, int protocol)
842{
843 return FreeRTOSTCPSocket::socket(domain, type, protocol);
844}
845
855int bind(int socket, const struct sockaddr *address, socklen_t address_len)
856{
857 return FreeRTOSTCPSocket::bind(socket, address, address_len);
858}
859
869int listen(int socket, int backlog)
870{
871 return FreeRTOSTCPSocket::listen(socket, backlog);
872}
873
888int accept(int socket, struct sockaddr *address, socklen_t *address_len)
889{
890 return FreeRTOSTCPSocket::accept(socket, address, address_len);
891}
892
901int connect(int socket, const struct sockaddr *address, socklen_t address_len)
902{
903 return FreeRTOSTCPSocket::connect(socket, address, address_len);
904}
905
917ssize_t recv(int socket, void *buffer, size_t length, int flags)
918{
919 return FreeRTOSTCPSocket::recv(socket, buffer, length, flags);
920}
921
930ssize_t send(int socket, const void *buffer, size_t length, int flags)
931{
932 return FreeRTOSTCPSocket::send(socket, buffer, length, flags);
933}
934
945int setsockopt(int socket, int level, int option_name, const void *option_value,
946 socklen_t option_len)
947{
949 socket, level, option_name, option_value, option_len);
950}
951
962int getsockopt(int socket, int level, int option_name, void *option_value,
963 socklen_t *option_len)
964{
966 socket, level, option_name, option_value, option_len);
967}
968
976int getsockname(int socket, struct sockaddr &addr, socklen_t &namelen)
977{
978 return 0;
979}
980
981static char str[32];
982
987const char *inet_ntoa(struct in_addr addr)
988{
989 // static char str[32];
990 FreeRTOS_inet_ntoa(addr.s_addr, str);
991 return str;
992}
993
999uint32_t inet_addr(const char *name)
1000{
1001 return FreeRTOS_inet_addr(name);
1002}
1003} /* extern "C" */
ssize_t recv(int socket, void *buffer, size_t length, int flags)
Receive a message from a connection-mode or connectionless-mode socket.
int accept(int socket, struct sockaddr *address, socklen_t *address_len)
Accept a new connection on a socket.
int setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len)
Set the socket options.
const char * inet_ntoa(struct in_addr addr)
Converts internet address into a dotted decimal string.
int bind(int socket, const struct sockaddr *address, socklen_t address_len)
Bind a name to a socket.
ssize_t send(int socket, const void *buffer, size_t length, int flags)
Initiate transmission of a message from the specified socket.
uint32_t inet_addr(const char *name)
Converts the dotted decmail internet address string into a binary representation.
int getsockopt(int socket, int level, int option_name, void *option_value, socklen_t *option_len)
Get the socket options.
int getsockname(int socket, struct sockaddr &addr, socklen_t &namelen)
Get the socket name.
int listen(int socket, int backlog)
Mark a connection-mode socket, specified by the socket argument, as accepting connections.
int connect(int socket, const struct sockaddr *address, socklen_t address_len)
Connect a socket.
int socket(int domain, int type, int protocol)
Create an unbound socket in a communications domain.
static void fd_free(int fd)
Free up a file descriptor.
Definition Fileio.cxx:71
static File * file_lookup(int fd)
Looks up a reference to a File corresponding to a given file descriptor.
Definition Fileio.cxx:82
static int fd_alloc(void)
Allocate a free file descriptor.
Definition Fileio.cxx:47
static OSMutex mutex
mutual exclusion for fileio
Definition Devtab.hxx:264
static int setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len)
Set the socket options.
bool writeActive
indicates our "best guess" at current socket's write active status
FreeRTOSTCPSocket()
Constructor.
static int socket(int domain, int type, int protocol)
Create an unbound socket in a communications domain.
int close(File *file) override
Close method.
static FreeRTOSTCPSocket * get_sd_by_index(int inx)
Get the socket descriptor assoicated with socket index.
static void remove_instance_from_sd(Socket_t sd)
Remove the FreeRTOSTCP instance from the active FreeRTOSTCP list.
static int listen(int socket, int backlog)
Mark a connection-mode socket, specified by the socket argument, as accepting connections.
static int accept(int socket, struct sockaddr *address, socklen_t *address_len)
Accept a new connection on a socket.
bool readActive
indicates our "best guess" at current socket's read active status
bool select(File *file, int mode) override
Device select method.
static FreeRTOSTCPSocket * get_instance_from_sd(Socket_t sd)
Get the FreeRTOSTCP instance given a specific socket descriptor.
static int getsockopt(int socket, int level, int option_name, void *option_value, socklen_t *option_len)
Get the socket options.
static ssize_t recv(int socket, void *buffer, size_t length, int flags)
Receive a message from a connection-mode or connectionless-mode socket.
static ssize_t send(int socket, const void *buffer, size_t length, int flags)
Initiate transmission of a message from the specified socket.
static int connect(int socket, const struct sockaddr *address, socklen_t address_len)
Connect a socket.
Socket_t sd
FreeRTOS socket descriptor.
int fcntl(File *file, int cmd, unsigned long data) override
Manipulate a file descriptor.
static int alloc_instance(Socket_t sd)
Allocate a new FreeRTOSTCPSocket and related structures.
bool listenActive
This is a listen socket.
static int bind(int socket, const struct sockaddr *address, socklen_t address_len)
Bind a name to a socket.
void fd_set_read(Socket_t socket)
Add socket to the read fd set.
void select_wakeup(Socket_t data=nullptr)
Asynchronously wakeup the select call.
void fd_set_write(Socket_t socket)
Add socket to the write fd set.
unsigned int references_
number of open references
Definition Devtab.hxx:592
mode_t mode_
File open mode, such as O_NONBLOCK.
Definition Devtab.hxx:590
void lock()
Lock a mutex.
Definition OS.hxx:446
void unlock()
Unlock a mutex.
Definition OS.hxx:453
static FreeRTOSTCP * instance()
Definition Singleton.hxx:77
SelectInfo selInfoRd
select wakeup metadata for read active
Definition Socket.hxx:79
SelectInfo selInfoWr
select wakeup metadata for write active
Definition Socket.hxx:80
#define FWRITE
Workaround for missing header defines on some newlib versions.
Definition fcntl.h:58
#define FREAD
Workaround for missing header defines on some newlib versions.
Definition fcntl.h:53
#define IPPROTO_TCP
TCP Raw Socket.
Definition in.h:70
#define IPPROTO_UDP
UDP Raw Socket.
Definition in.h:73
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
Definition macros.h:138
#define SOCK_STREAM
TCP Socket.
Definition socket.h:45
uint32_t socklen_t
type of sockaddr lenth
Definition socket.h:89
#define SOCK_DGRAM
UDP Socket.
Definition socket.h:48
#define SO_REUSEADDR
socket option to reuse address
Definition socket.h:67
#define SOL_SOCKET
socket option category
Definition socket.h:64
#define AF_INET
IPv4 Socket (UDP, TCP, etc...)
Definition socket.h:54
#define SO_SNDTIMEO
socket option send timeout
Definition socket.h:73
#define SO_RCVTIMEO
socket option receive timout
Definition socket.h:70
static void select_insert(SelectInfo *info)
Add client to list of clients needing woken.
Definition Select.cxx:197
File information.
Definition Devtab.hxx:52
int flags
open flags
Definition Devtab.hxx:63
void * priv
file reference specific data "pointer"
Definition Devtab.hxx:57
FileIO * dev
file operations
Definition Devtab.hxx:53
Structure describing an Internet address.
Definition in.h:49
in_addr_t s_addr
Address.
Definition in.h:51
Structure describing an Internet socket address.
Definition in.h:56
uint16_t sin_family
protocol family (AF_INET)
Definition in.h:57
uint16_t sin_port
port number
Definition in.h:58
struct in_addr sin_addr
internet address
Definition in.h:59
IPv4 socket address.
Definition socket.h:83
uint16_t sa_family
address family (e.g.
Definition socket.h:84
#define TCP_NODELAY
don't delay send to coalesce packets
Definition tcp.h:42