47#include "FreeRTOS_IP.h"
48#include "FreeRTOS_Sockets.h"
50#include "FreeRTOSTCPSocket.hxx"
61 if (new_socket ==
nullptr)
80 domain = FREERTOS_AF_INET;
91 type = FREERTOS_SOCK_STREAM;
94 type = FREERTOS_SOCK_DGRAM;
107 protocol = FREERTOS_IPPROTO_TCP;
110 protocol = FREERTOS_IPPROTO_UDP;
118 Socket_t
sd = FreeRTOS_socket(domain, type, protocol);
120 if (
sd == FREERTOS_INVALID_SOCKET)
130 file->
dev = new_socket;
131 file->
flags = O_RDWR;
132 file->
priv = new_socket;
137 portENTER_CRITICAL();
138 for (
int i = 1; i < MAX_SOCKETS; ++i)
140 if (FreeRTOSTCPSockets[i] == NULL)
142 FreeRTOSTCPSockets[i] = new_socket;
165 if (!S_ISSOCK(s->
mode_))
171 struct freertos_sockaddr fr_address;
172 fr_address.sin_len =
sizeof(fr_address);
177 fr_address.sin_family = FREERTOS_AF_INET;
186 fr_address.sin_port = sin->
sin_port;
188 int result = FreeRTOS_bind(s->
sd, &fr_address,
sizeof(fr_address));
194 case -FREERTOS_EINVAL:
220 if (!S_ISSOCK(s->
mode_))
226 int result = FreeRTOS_listen(s->
sd, backlog);
232 case -pdFREERTOS_ERRNO_EOPNOTSUPP:
263 if (!S_ISSOCK(s->
mode_))
275 freertos_sockaddr fr_address;
276 socklen_t fr_address_len =
sizeof(fr_address);
278 Socket_t
sd = FreeRTOS_accept(s->
sd, &fr_address, &fr_address_len);
280 if (address && address_len && (*address_len >=
sizeof(
sockaddr_in)))
283 sin->
sin_port = fr_address.sin_port;
295 if (
sd == FREERTOS_INVALID_SOCKET)
304 const TickType_t timeout = portMAX_DELAY;
305 result = FreeRTOS_setsockopt(
sd, 0, FREERTOS_SO_RCVTIMEO, &timeout, 0);
310 result = FreeRTOS_setsockopt(
sd, 0, FREERTOS_SO_SNDTIMEO, &timeout, 0);
337 if (!S_ISSOCK(s->
mode_))
343 struct freertos_sockaddr fr_address;
344 socklen_t fr_address_len =
sizeof(fr_address);
345 fr_address.sin_len =
sizeof(fr_address);
350 fr_address.sin_family = FREERTOS_AF_INET;
358 fr_address.sin_port = sin->
sin_port;
360 int result = FreeRTOS_connect(s->
sd, &fr_address, fr_address_len);
366 case -pdFREERTOS_ERRNO_EBADF:
369 case -pdFREERTOS_ERRNO_EISCONN:
372 case -pdFREERTOS_ERRNO_EINPROGRESS:
373 case -pdFREERTOS_ERRNO_EAGAIN:
376 case -FREERTOS_EWOULDBLOCK:
379 case -pdFREERTOS_ERRNO_ETIMEDOUT:
395 int socket,
void *buffer,
size_t length,
int flags)
408 if (!S_ISSOCK(s->
mode_))
414 int result = FreeRTOS_recv(s->
sd, buffer, length, flags);
427 case -pdFREERTOS_ERRNO_ENOMEM:
430 case -pdFREERTOS_ERRNO_ENOTCONN:
433 case -pdFREERTOS_ERRNO_EINTR:
436 case -pdFREERTOS_ERRNO_EINVAL:
445 if ((
size_t)result < length)
461 int socket,
const void *buffer,
size_t length,
int flags)
474 if (!S_ISSOCK(s->
mode_))
480 int result = FreeRTOS_send(s->
sd, buffer, length, flags);
486 case -pdFREERTOS_ERRNO_ENOTCONN:
489 case -pdFREERTOS_ERRNO_ENOMEM:
492 case -pdFREERTOS_ERRNO_EINVAL:
495 case -pdFREERTOS_ERRNO_ENOSPC:
504 if ((
size_t)result < length)
520 const void *option_value,
socklen_t option_len)
530 if (!S_ISSOCK(s->
mode_))
538 const struct timeval *tm;
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)
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)
592 result = FreeRTOS_setsockopt(
593 s->
sd, level, option_name, option_value, option_len);
599 case -FREERTOS_EINVAL:
616 void *option_value,
socklen_t *option_len)
626 if (!S_ISSOCK(s->
mode_))
675 portENTER_CRITICAL();
689 portENTER_CRITICAL();
717 if ((inx < 0) || (inx > MAX_SOCKETS))
721 return FreeRTOSTCPSockets[inx];
742 file->
dev = new_socket;
743 file->
flags = O_RDWR;
744 file->
priv = new_socket;
749 portENTER_CRITICAL();
750 for (
int i = 1; i < MAX_SOCKETS; ++i)
752 if (FreeRTOSTCPSockets[i] ==
nullptr)
754 FreeRTOSTCPSockets[i] = new_socket;
767 for (
int i = 0; i < MAX_SOCKETS; ++i)
769 if (
sd == FreeRTOSTCPSockets[i]->
sd)
771 return FreeRTOSTCPSockets[i];
783 for (
int i = 0; i < MAX_SOCKETS; ++i)
785 if (
sd == FreeRTOSTCPSockets[i]->
sd)
787 FreeRTOSTCPSockets[i] = NULL;
800 if (!S_ISSOCK(s->
mode_))
809 if (data & O_NONBLOCK)
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));
841int socket(
int domain,
int type,
int protocol)
917ssize_t
recv(
int socket,
void *buffer,
size_t length,
int flags)
930ssize_t
send(
int socket,
const void *buffer,
size_t length,
int flags)
949 socket, level, option_name, option_value, option_len);
966 socket, level, option_name, option_value, option_len);
990 FreeRTOS_inet_ntoa(addr.
s_addr, str);
1001 return FreeRTOS_inet_addr(name);
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.
static File * file_lookup(int fd)
Looks up a reference to a File corresponding to a given file descriptor.
static int fd_alloc(void)
Allocate a free file descriptor.
static OSMutex mutex
mutual exclusion for fileio
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
mode_t mode_
File open mode, such as O_NONBLOCK.
void unlock()
Unlock a mutex.
static FreeRTOSTCP * instance()
SelectInfo selInfoRd
select wakeup metadata for read active
SelectInfo selInfoWr
select wakeup metadata for write active
#define FWRITE
Workaround for missing header defines on some newlib versions.
#define FREAD
Workaround for missing header defines on some newlib versions.
#define IPPROTO_TCP
TCP Raw Socket.
#define IPPROTO_UDP
UDP Raw Socket.
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
#define SOCK_STREAM
TCP Socket.
uint32_t socklen_t
type of sockaddr lenth
#define SOCK_DGRAM
UDP Socket.
#define SO_REUSEADDR
socket option to reuse address
#define SOL_SOCKET
socket option category
#define AF_INET
IPv4 Socket (UDP, TCP, etc...)
#define SO_SNDTIMEO
socket option send timeout
#define SO_RCVTIMEO
socket option receive timout
static void select_insert(SelectInfo *info)
Add client to list of clients needing woken.
void * priv
file reference specific data "pointer"
FileIO * dev
file operations
Structure describing an Internet address.
Structure describing an Internet socket address.
uint16_t sin_family
protocol family (AF_INET)
uint16_t sin_port
port number
struct in_addr sin_addr
internet address
uint16_t sa_family
address family (e.g.
#define TCP_NODELAY
don't delay send to coalesce packets