34#define SUPPORT_SL_R1_API
50#include <ti/drivers/net/wifi/simplelink.h>
71#define CC32XX_SOCKET_RESERVED ((CC32xxSocket *)(&reservedPtr))
94 std::unique_ptr<CC32xxSocket> new_socket(
new CC32xxSocket());
95 if (new_socket.get() ==
nullptr)
109 domain = SL_AF_INET6;
112 domain = SL_AF_PACKET;
117 errno = EAFNOSUPPORT;
124 type = SL_SOCK_STREAM;
127 type = SL_SOCK_DGRAM;
144 protocol = SL_IPPROTO_TCP;
147 protocol = SL_IPPROTO_UDP;
150 protocol = SL_IPPROTO_RAW;
153 protocol = SL_SEC_SOCKET;
162 int result = sl_Socket(domain, type, protocol);
171 case SL_ERROR_BSD_EAFNOSUPPORT:
172 errno = EAFNOSUPPORT;
174 case SL_ERROR_BSD_EPROTOTYPE:
177 case SL_ERROR_BSD_EACCES:
180 case SL_ERROR_BSD_ENSOCK:
183 case SL_ERROR_BSD_ENOMEM:
186 case SL_ERROR_BSD_EINVAL:
189 case SL_ERROR_BSD_EPROTONOSUPPORT:
190 errno = EPROTONOSUPPORT;
192 case SL_ERROR_BSD_EOPNOTSUPP:
205 file->
dev = new_socket.get();
206 file->
flags = O_RDWR;
207 file->
priv = new_socket.get();
209 new_socket->sd = result;
210 new_socket->references_ = 1;
230 SlSockAddr_t sl_address;
231 sl_address.sa_family = address->
sa_family;
232 memcpy(sl_address.sa_data, address->
sa_data,
sizeof(sl_address.sa_data));
234 int result = sl_Bind(s->
sd, &sl_address, address_len);
261 int result = sl_Listen(s->
sd, backlog);
300 SlSockAddr_t sl_address;
301 SlSocklen_t sl_address_len;
303 int result = sl_Accept(s->
sd, &sl_address, &sl_address_len);
305 if (address && address_len)
307 memcpy(address, &sl_address, *address_len);
317 case SL_ERROR_BSD_ENSOCK:
320 case SL_POOL_IS_EMPTY:
323 case SL_ERROR_BSD_EAGAIN:
326 case SL_RET_CODE_STOP_IN_PROGRESS:
327 errno = ECONNABORTED;
351 std::unique_ptr<CC32xxSocket> new_socket(
new CC32xxSocket());
352 if (new_socket.get() ==
nullptr)
363 file->
dev = new_socket.get();
364 file->
flags = O_RDWR;
365 file->
priv = new_socket.get();
367 new_socket->sd = result;
368 new_socket->references_ = 1;
388 SlSockAddr_t sl_address;
389 sl_address.sa_family = address->
sa_family;
390 memcpy(sl_address.sa_data, address->
sa_data,
sizeof(sl_address.sa_data));
392 int result = sl_Connect(s->
sd, &sl_address, address_len);
403 case SL_RET_CODE_STOP_IN_PROGRESS:
406 case SL_ERROR_BSD_EISCONN:
409 case SL_ERROR_BSD_ECONNREFUSED:
410 errno = ECONNREFUSED;
412 case SL_ERROR_BSD_EALREADY:
419 case SL_POOL_IS_EMPTY:
422 case SL_ERROR_BSD_EAGAIN:
447 int result = sl_Recv(s->
sd, buffer, length, flags);
456 case SL_POOL_IS_EMPTY:
459 case SL_ERROR_BSD_EAGAIN:
463 case SL_ERROR_BSD_ECONNREFUSED:
466 case SL_ERROR_BSD_EBADF:
469 case SL_RET_CODE_STOP_IN_PROGRESS:
503 int result = sl_Send(s->
sd, buffer, length, flags);
507 LOG_ERROR(
"sl socket write return error %d", result);
510 case SL_ERROR_BSD_SOC_ERROR:
514 case SL_ERROR_BSD_EAGAIN:
518 case SL_ERROR_BSD_EBADF:
536 const void *option_value,
socklen_t option_len)
564 const struct timeval *tm;
565 struct SlTimeval_t timeval;
567 tm =
static_cast<const struct timeval *
>(option_value);
568 timeval.tv_sec = tm->tv_sec;
569 timeval.tv_usec = tm->tv_usec;
570 result = sl_SetSockOpt(s->
sd, SL_SOL_SOCKET,
571 SL_SO_RCVTIMEO, &timeval,
577 SlSocklen_t sl_option_len = option_len;
579 result = sl_SetSockOpt(s->
sd, SL_SOL_SOCKET, SL_SO_RCVBUF,
580 option_value, sl_option_len);
585 SlSocklen_t sl_option_len = option_len;
587 result = sl_SetSockOpt(s->
sd, SL_SOL_SOCKET,
588 SL_SO_KEEPALIVETIME, option_value, sl_option_len);
625 void *option_value,
socklen_t *option_len)
652 int *so_reuseaddr =
static_cast<int *
>(option_value);
654 *option_len =
sizeof(int);
661 struct SlTimeval_t timeval;
662 SlSocklen_t sl_option_len =
sizeof(timeval);
664 tm =
static_cast<struct timeval *
>(option_value);
665 result = sl_GetSockOpt(s->
sd, SL_SOL_SOCKET,
666 SL_SO_RCVTIMEO, &timeval,
668 tm->tv_sec = timeval.tv_sec;
669 tm->tv_usec = timeval.tv_usec;
670 *option_len =
sizeof(
struct timeval);
675 SlSocklen_t sl_option_len = *option_len;
677 result = sl_GetSockOpt(s->
sd, SL_SOL_SOCKET, SL_SO_RCVBUF,
678 option_value, &sl_option_len);
679 *option_len = sl_option_len;
684 SlSocklen_t sl_option_len = *option_len;
686 result = sl_GetSockOpt(s->
sd, SL_SOL_SOCKET,
687 SL_SO_KEEPALIVETIME, option_value, &sl_option_len);
688 *option_len = sl_option_len;
704 int *tcp_nodelay =
static_cast<int *
>(option_value);
706 *option_len =
sizeof(int);
719 int *opt_sd =
static_cast<int *
>(option_value);
721 *option_len =
sizeof(int);
755 portENTER_CRITICAL();
783 portENTER_CRITICAL();
797 portENTER_CRITICAL();
824 for (
int i = 0; i < SL_MAX_SOCKETS; ++i)
853 if (!S_ISSOCK(
stat.st_mode))
867 for (
int i = 0; i < SL_MAX_SOCKETS; ++i)
887 portENTER_CRITICAL();
888 for (i = 0; i < SL_MAX_SOCKETS; ++i)
898 if (i == SL_MAX_SOCKETS)
914 if (!S_ISSOCK(s->
mode_))
927 SlSockNonblocking_t sl_option_value;
928 sl_option_value.NonBlockingEnabled = data & O_NONBLOCK ? 1 : 0;
929 int result = sl_SetSockOpt(s->
sd, SL_SOL_SOCKET,
930 SL_SO_NONBLOCKING, &sl_option_value,
931 sizeof(sl_option_value));
933 if (data & O_NONBLOCK)
939 mode_ &= ~O_NONBLOCK;
960int socket(
int domain,
int type,
int protocol)
1049ssize_t
send(
int socket,
const void *buffer,
size_t length,
int flags)
1065 const void *option_value,
socklen_t option_len)
1068 option_value, option_len);
1082 void *option_value,
socklen_t *option_len)
1085 option_value, option_len);
1098 return "gai_strerror unkown";
1100 return "temporary failure";
1102 return "non-recoverable failure";
1104 return "memory allocation failure";
1135 uint32_t ip_addr[4];
1139 uint16_t text_len = 120;
1141 std::unique_ptr<struct addrinfo> ai(
new struct addrinfo);
1142 if (ai.get() ==
nullptr)
1146 memset(ai.get(), 0,
sizeof(
struct addrinfo));
1148 std::unique_ptr<struct sockaddr> sa(
new struct sockaddr);
1149 if (sa.get() ==
nullptr)
1153 memset(sa.get(), 0,
sizeof(
struct sockaddr));
1158 domain = SL_AF_INET;
1161 domain = SL_AF_INET6;
1164 domain = SL_AF_PACKET;
1167 errno = EAFNOSUPPORT;
1175 result = sl_NetAppDnsGetHostByName((int8_t*)nodename, strlen(nodename),
1180 result = sl_NetAppDnsGetHostByService((int8_t*)servname,
1181 strlen(servname), domain, ip_addr,
1182 &port, &text_len, text);
1190 case SL_POOL_IS_EMPTY:
1192 case SL_ERROR_NET_APP_DNS_QUERY_NO_RESPONSE:
1193 case SL_ERROR_NET_APP_DNS_NO_SERVER:
1194 case SL_ERROR_NET_APP_DNS_QUERY_FAILED:
1195 case SL_ERROR_NET_APP_DNS_MALFORMED_PACKET:
1196 case SL_ERROR_NET_APP_DNS_MISMATCHED_RESPONSE:
1212 long port_name = strtol(servname,
nullptr, 0);
1217 if (port_name == 0 && (servname[0] <
'0' || servname[0] >
'9') &&
1218 servname[0] !=
'+' && servname[0] !=
'-')
1232 errno = EAFNOSUPPORT;
1236 *res = ai.release();
1237 (*res)->
ai_addr = sa.release();
1251 errno = EAFNOSUPPORT;
1258 uint8_t *ip = (uint8_t*)src;
1259 for (
int i = 0; i < 4; ++i)
1262 char *end = integer_to_buffer(ip[i],
string);
1263 count += (end - string) + 1;
1269 strcpy(dst,
string);
1270 dst += (end - string);
1290 std::unique_ptr<struct ifaddrs> ia(
new struct ifaddrs);
1291 if (ia.get() ==
nullptr)
1296 memset(ia.get(), 0,
sizeof(
struct ifaddrs));
1298 std::unique_ptr<char[]> ifa_name(
new char[6]);
1299 if (ifa_name.get() ==
nullptr)
1305 std::unique_ptr<struct sockaddr> ifa_addr(
new struct sockaddr);
1306 if (ifa_addr ==
nullptr)
1311 memset(ifa_addr.get(), 0,
sizeof(
struct sockaddr));
1315 std::unique_ptr<struct sockaddr> ifa_netmask(
new struct sockaddr);
1316 if (ifa_netmask ==
nullptr)
1321 memset(ifa_netmask.get(), 0,
sizeof(
struct sockaddr));
1323 std::unique_ptr<struct sockaddr> ifa_broadaddr(
new struct sockaddr);
1324 if (ifa_broadaddr ==
nullptr)
1329 memset(ifa_broadaddr.get(), 0,
sizeof(
struct sockaddr));
1333 strcpy(ifa_name.get(),
"wlan0");
1340 ia.get()->ifa_next =
nullptr;
1341 ia.get()->ifa_name = ifa_name.release();
1342 ia.get()->ifa_flags = 0;
1343 ia.get()->ifa_addr = ifa_addr.release();
1344 ia.get()->ifa_netmask =
nullptr;
1345 ia.get()->ifa_ifu.ifu_broadaddr =
nullptr;
1346 ia.get()->ifa_data =
nullptr;
1349 *ifap = ia.release();
void SlCheckResult(int result, int expected)
Tests that a SimpleLink request has succeeded.
Socket implementation for the CC32xx class WiFi devices.
int16_t sd
CC32xx socket descriptor.
static int reserve_socket()
Reserve a location in the cc32xxSockets pool.
bool select(File *file, int mode) override
Device select method.
static CC32xxSocket * get_instance_from_fd(int fd)
Get the CC32xxSocket instance given a file descriptor.
static int connect(int socket, const struct sockaddr *address, socklen_t address_len)
Connect a socket.
uint8_t readActive
indicates our "best guess" at current socket's read active status
static int setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len)
Set the socket options.
static int getsockopt(int socket, int level, int option_name, void *option_value, socklen_t *option_len)
Get the socket options.
uint8_t listenActive
This is a listen socket.
int fcntl(File *file, int cmd, unsigned long data) override
Manipulate a file descriptor.
static int bind(int socket, const struct sockaddr *address, socklen_t address_len)
Bind a name to a socket.
static CC32xxSocket * get_instance_from_sd(int sd)
Get the CC32xxSocket instance given a specific CC32xx socket descriptor.
CC32xxSocket()
Constructor.
static int listen(int socket, int backlog)
Mark a connection-mode socket, specified by the socket argument, as accepting connections.
static void remove_instance_from_sd(int sd)
Remove the CC32xxSocket instance from the active CC32xxSocket list.
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 int accept(int socket, struct sockaddr *address, socklen_t *address_len)
Accept a new connection on a socket.
static ssize_t send(int socket, const void *buffer, size_t length, int flags)
Initiate transmission of a message from the specified socket.
uint8_t writeActive
indicates our "best guess" at current socket's write active status
static ssize_t recv(int socket, void *buffer, size_t length, int flags)
Receive a message from a connection-mode or connectionless-mode socket.
void fd_remove(int16_t sd)
Remove a socket from the known sockets that might be part of the sl_Select fdset.
void fd_set_read(int16_t sd)
Add socket to the read fd set.
void fd_set_write(int16_t sd)
Add socket to the write fd set.
static constexpr unsigned IPPROTO_TCP_TLS
Pass this option as protocol to socket to create a secure socket.
static constexpr unsigned SO_SIMPLELINK_SD
Retrieves the socket descriptor for setting TLS parameters.
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
virtual int fstat(File *file, struct stat *stat) override
Get the status information of a file or device.
unsigned int references_
number of open references
mode_t mode_
File open mode, such as O_NONBLOCK.
void unlock()
Unlock a mutex.
static CC32xxWiFi * 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_RAW
Raw Socket.
#define htons(x)
Converts a host endian short value to network endian.
#define IPPROTO_TCP
TCP Raw Socket.
#define IPPROTO_UDP
UDP Raw Socket.
#define htonl(x)
Converts a host endian long value to network endian.
#define LOG_ERROR(message...)
Shorthand for LOG(LEVEL_ERROR, message...). See LOG.
#define HASSERT(x)
Checks that the value of expression x is true, else terminates the current process.
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.
int bind(int socket, const struct sockaddr *address, socklen_t address_len)
Bind a name to a socket.
void freeaddrinfo(struct addrinfo *ai)
see 'man freeaddrinfo'
ssize_t send(int socket, const void *buffer, size_t length, int flags)
Initiate transmission of a message from the specified socket.
#define CC32XX_SOCKET_RESERVED
Guard value indivating a reserved socket that is currently being allocated.
const char * gai_strerror(int __ecode)
see 'man gai_strerror'
int getifaddrs(struct ifaddrs **ifap)
Create a linked list of structures describing the network interfaces of the local system.
int getsockopt(int socket, int level, int option_name, void *option_value, socklen_t *option_len)
Get the socket options.
int listen(int socket, int backlog)
Mark a connection-mode socket, specified by the socket argument, as accepting connections.
int getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
see 'man getaddrinfo'
const char * inet_ntop(int af, const void *src, char *dst, socklen_t size)
Convert the network address in src to a character string in src.
static volatile uint8_t reservedPtr
Dummy pointer address that can be used as a reserved indicator.
static CC32xxSocket * cc32xxSockets[SL_MAX_SOCKETS]
Existing (allocated) sockets.
int connect(int socket, const struct sockaddr *address, socklen_t address_len)
Connect a socket.
void freeifaddrs(struct ifaddrs *ifa)
Free a previously generated linked list of structures describing the network interfaces of the local ...
int socket(int domain, int type, int protocol)
Create an unbound socket in a communications domain.
#define EAI_MEMORY
Memory allocation failure.
#define EAI_AGAIN
Temporary failure in name resolution.
#define EAI_FAIL
, Non-recoverable failure in name res
#define SO_RCVBUF
socket option for receive buffer size
#define SOCK_STREAM
TCP Socket.
#define SOCK_RAW
Raw Socket.
uint32_t socklen_t
type of sockaddr lenth
#define SO_KEEPALIVETIME
socket option to set TCP keepalive timeout
#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 AF_INET6
IPv6 Socket (UDP, TCP, etc...)
#define SO_RCVTIMEO
socket option receive timout
static void select_insert(SelectInfo *info)
Add client to list of clients needing woken.
static int stat(struct _reent *reent, const char *path, struct stat *stat)
Get the status information of a file or device.
void * priv
file reference specific data "pointer"
FileIO * dev
file operations
Structure to contain information about address of a service provider.
struct sockaddr * ai_addr
Socket address for socket.
char * ai_canonname
Canonical name for service location.
int ai_socktype
Socket type.
int ai_protocol
Protocol for socket.
int ai_family
Protocol family for socket.
network interface address list member
char * ifa_name
name of interface.
struct sockaddr * ifa_netmask
netmask of interface
void * ifa_data
address-specific data
struct ifaddrs * ifa_next
next item in list
struct sockaddr * ifu_broadaddr
broadcast address of interface
struct sockaddr * ifa_addr
address of interface
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.
uint8_t sa_data[14]
protocol specific address information
#define TCP_NODELAY
don't delay send to coalesce packets