1
0
Fork 0

Squashed 'tmk_core/' changes from 7967731..b9e0ea0

b9e0ea0 Merge commit '7fa9d8bdea3773d1195b04d98fcf27cf48ddd81d' as 'tool/mbed/mbed-sdk'
7fa9d8b Squashed 'tool/mbed/mbed-sdk/' content from commit 7c21ce5

git-subtree-dir: tmk_core
git-subtree-split: b9e0ea08cb940de20b3610ecdda18e9d8cd7c552
This commit is contained in:
Jun Wako 2015-04-24 16:26:14 +09:00
parent a20ef7052c
commit 1fe4406f37
4198 changed files with 2016457 additions and 0 deletions

View file

@ -0,0 +1,73 @@
/* Copyright (C) 2012 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "Socket/Socket.h"
#include "Socket/Endpoint.h"
#include <cstring>
#include <cstdio>
Endpoint::Endpoint() {
reset_address();
}
Endpoint::~Endpoint() {}
void Endpoint::reset_address(void) {
std::memset(&_remoteHost, 0, sizeof(struct sockaddr_in));
_ipAddress[0] = '\0';
}
#include "stdio.h"
int Endpoint::set_address(const char* host, const int port) {
reset_address();
// IP Address
char address[5];
char *p_address = address;
// Dot-decimal notation
int result = std::sscanf(host, "%3u.%3u.%3u.%3u",
(unsigned int*)&address[0], (unsigned int*)&address[1],
(unsigned int*)&address[2], (unsigned int*)&address[3]);
if (result != 4) {
// Resolve address with DNS
struct hostent *host_address = lwip_gethostbyname(host);
if (host_address == NULL)
return -1; //Could not resolve address
p_address = (char*)host_address->h_addr_list[0];
}
std::memcpy((char*)&_remoteHost.sin_addr.s_addr, p_address, 4);
// Address family
_remoteHost.sin_family = AF_INET;
// Set port
_remoteHost.sin_port = htons(port);
return 0;
}
char* Endpoint::get_address() {
if ((_ipAddress[0] == '\0') && (_remoteHost.sin_addr.s_addr != 0))
inet_ntoa_r(_remoteHost.sin_addr, _ipAddress, sizeof(_ipAddress));
return _ipAddress;
}
int Endpoint::get_port() {
return ntohs(_remoteHost.sin_port);
}

View file

@ -0,0 +1,63 @@
/* Copyright (C) 2012 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef ENDPOINT_H
#define ENDPOINT_H
class UDPSocket;
/**
IP Endpoint (address, port)
*/
class Endpoint {
friend class UDPSocket;
public:
/** IP Endpoint (address, port)
*/
Endpoint(void);
~Endpoint(void);
/** Reset the address of this endpoint
*/
void reset_address(void);
/** Set the address of this endpoint
\param host The endpoint address (it can either be an IP Address or a hostname that will be resolved with DNS).
\param port The endpoint port
\return 0 on success, -1 on failure (when an hostname cannot be resolved by DNS).
*/
int set_address(const char* host, const int port);
/** Get the IP address of this endpoint
\return The IP address of this endpoint.
*/
char* get_address(void);
/** Get the port of this endpoint
\return The port of this endpoint
*/
int get_port(void);
protected:
char _ipAddress[17];
struct sockaddr_in _remoteHost;
};
#endif

View file

@ -0,0 +1,91 @@
/* Copyright (C) 2012 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "Socket/Socket.h"
#include <cstring>
using std::memset;
Socket::Socket() : _sock_fd(-1), _blocking(true), _timeout(1500) {
}
void Socket::set_blocking(bool blocking, unsigned int timeout) {
_blocking = blocking;
_timeout = timeout;
}
int Socket::init_socket(int type) {
if (_sock_fd != -1)
return -1;
int fd = lwip_socket(AF_INET, type, 0);
if (fd < 0)
return -1;
_sock_fd = fd;
return 0;
}
int Socket::set_option(int level, int optname, const void *optval, socklen_t optlen) {
return lwip_setsockopt(_sock_fd, level, optname, optval, optlen);
}
int Socket::get_option(int level, int optname, void *optval, socklen_t *optlen) {
return lwip_getsockopt(_sock_fd, level, optname, optval, optlen);
}
int Socket::select(struct timeval *timeout, bool read, bool write) {
fd_set fdSet;
FD_ZERO(&fdSet);
FD_SET(_sock_fd, &fdSet);
fd_set* readset = (read ) ? (&fdSet) : (NULL);
fd_set* writeset = (write) ? (&fdSet) : (NULL);
int ret = lwip_select(FD_SETSIZE, readset, writeset, NULL, timeout);
return (ret <= 0 || !FD_ISSET(_sock_fd, &fdSet)) ? (-1) : (0);
}
int Socket::wait_readable(TimeInterval& timeout) {
return select(&timeout._time, true, false);
}
int Socket::wait_writable(TimeInterval& timeout) {
return select(&timeout._time, false, true);
}
int Socket::close(bool shutdown) {
if (_sock_fd < 0)
return -1;
if (shutdown)
lwip_shutdown(_sock_fd, SHUT_RDWR);
lwip_close(_sock_fd);
_sock_fd = -1;
return 0;
}
Socket::~Socket() {
close(); //Don't want to leak
}
TimeInterval::TimeInterval(unsigned int ms) {
_time.tv_sec = ms / 1000;
_time.tv_usec = (ms - (_time.tv_sec * 1000)) * 1000;
}

View file

@ -0,0 +1,104 @@
/* Copyright (C) 2012 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef SOCKET_H_
#define SOCKET_H_
#include "lwip/sockets.h"
#include "lwip/netdb.h"
//DNS
inline struct hostent *gethostbyname(const char *name) {
return lwip_gethostbyname(name);
}
inline int gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) {
return lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop);
}
class TimeInterval;
/** Socket file descriptor and select wrapper
*/
class Socket {
public:
/** Socket
*/
Socket();
/** Set blocking or non-blocking mode of the socket and a timeout on
blocking socket operations
\param blocking true for blocking mode, false for non-blocking mode.
\param timeout timeout in ms [Default: (1500)ms].
*/
void set_blocking(bool blocking, unsigned int timeout=1500);
/** Set socket options
\param level stack level (see: lwip/sockets.h)
\param optname option ID
\param optval option value
\param socklen_t length of the option value
\return 0 on success, -1 on failure
*/
int set_option(int level, int optname, const void *optval, socklen_t optlen);
/** Get socket options
\param level stack level (see: lwip/sockets.h)
\param optname option ID
\param optval buffer pointer where to write the option value
\param socklen_t length of the option value
\return 0 on success, -1 on failure
*/
int get_option(int level, int optname, void *optval, socklen_t *optlen);
/** Close the socket
\param shutdown free the left-over data in message queues
*/
int close(bool shutdown=true);
~Socket();
protected:
int _sock_fd;
int init_socket(int type);
int wait_readable(TimeInterval& timeout);
int wait_writable(TimeInterval& timeout);
bool _blocking;
unsigned int _timeout;
private:
int select(struct timeval *timeout, bool read, bool write);
};
/** Time interval class used to specify timeouts
*/
class TimeInterval {
friend class Socket;
public:
/** Time Interval
\param ms time interval expressed in milliseconds
*/
TimeInterval(unsigned int ms);
private:
struct timeval _time;
};
#endif /* SOCKET_H_ */

View file

@ -0,0 +1,133 @@
/* Copyright (C) 2012 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "TCPSocketConnection.h"
#include <cstring>
using std::memset;
using std::memcpy;
TCPSocketConnection::TCPSocketConnection() :
_is_connected(false) {
}
int TCPSocketConnection::connect(const char* host, const int port) {
if (init_socket(SOCK_STREAM) < 0)
return -1;
if (set_address(host, port) != 0)
return -1;
if (lwip_connect(_sock_fd, (const struct sockaddr *) &_remoteHost, sizeof(_remoteHost)) < 0) {
close();
return -1;
}
_is_connected = true;
return 0;
}
bool TCPSocketConnection::is_connected(void) {
return _is_connected;
}
int TCPSocketConnection::send(char* data, int length) {
if ((_sock_fd < 0) || !_is_connected)
return -1;
if (!_blocking) {
TimeInterval timeout(_timeout);
if (wait_writable(timeout) != 0)
return -1;
}
int n = lwip_send(_sock_fd, data, length, 0);
_is_connected = (n != 0);
return n;
}
// -1 if unsuccessful, else number of bytes written
int TCPSocketConnection::send_all(char* data, int length) {
if ((_sock_fd < 0) || !_is_connected)
return -1;
int writtenLen = 0;
TimeInterval timeout(_timeout);
while (writtenLen < length) {
if (!_blocking) {
// Wait for socket to be writeable
if (wait_writable(timeout) != 0)
return writtenLen;
}
int ret = lwip_send(_sock_fd, data + writtenLen, length - writtenLen, 0);
if (ret > 0) {
writtenLen += ret;
continue;
} else if (ret == 0) {
_is_connected = false;
return writtenLen;
} else {
return -1; //Connnection error
}
}
return writtenLen;
}
int TCPSocketConnection::receive(char* data, int length) {
if ((_sock_fd < 0) || !_is_connected)
return -1;
if (!_blocking) {
TimeInterval timeout(_timeout);
if (wait_readable(timeout) != 0)
return -1;
}
int n = lwip_recv(_sock_fd, data, length, 0);
_is_connected = (n != 0);
return n;
}
// -1 if unsuccessful, else number of bytes received
int TCPSocketConnection::receive_all(char* data, int length) {
if ((_sock_fd < 0) || !_is_connected)
return -1;
int readLen = 0;
TimeInterval timeout(_timeout);
while (readLen < length) {
if (!_blocking) {
//Wait for socket to be readable
if (wait_readable(timeout) != 0)
return readLen;
}
int ret = lwip_recv(_sock_fd, data + readLen, length - readLen, 0);
if (ret > 0) {
readLen += ret;
} else if (ret == 0) {
_is_connected = false;
return readLen;
} else {
return -1; //Connnection error
}
}
return readLen;
}

View file

@ -0,0 +1,81 @@
/* Copyright (C) 2012 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef TCPSOCKET_H
#define TCPSOCKET_H
#include "Socket/Socket.h"
#include "Socket/Endpoint.h"
/**
TCP socket connection
*/
class TCPSocketConnection : public Socket, public Endpoint {
friend class TCPSocketServer;
public:
/** TCP socket connection
*/
TCPSocketConnection();
/** Connects this TCP socket to the server
\param host The host to connect to. It can either be an IP Address or a hostname that will be resolved with DNS.
\param port The host's port to connect to.
\return 0 on success, -1 on failure.
*/
int connect(const char* host, const int port);
/** Check if the socket is connected
\return true if connected, false otherwise.
*/
bool is_connected(void);
/** Send data to the remote host.
\param data The buffer to send to the host.
\param length The length of the buffer to send.
\return the number of written bytes on success (>=0) or -1 on failure
*/
int send(char* data, int length);
/** Send all the data to the remote host.
\param data The buffer to send to the host.
\param length The length of the buffer to send.
\return the number of written bytes on success (>=0) or -1 on failure
*/
int send_all(char* data, int length);
/** Receive data from the remote host.
\param data The buffer in which to store the data received from the host.
\param length The maximum length of the buffer.
\return the number of received bytes on success (>=0) or -1 on failure
*/
int receive(char* data, int length);
/** Receive all the data from the remote host.
\param data The buffer in which to store the data received from the host.
\param length The maximum length of the buffer.
\return the number of received bytes on success (>=0) or -1 on failure
*/
int receive_all(char* data, int length);
private:
bool _is_connected;
};
#endif

View file

@ -0,0 +1,78 @@
/* Copyright (C) 2012 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "TCPSocketServer.h"
#include <cstring>
using std::memset;
using std::memcpy;
TCPSocketServer::TCPSocketServer() {
}
int TCPSocketServer::bind(int port) {
if (init_socket(SOCK_STREAM) < 0)
return -1;
struct sockaddr_in localHost;
memset(&localHost, 0, sizeof(localHost));
localHost.sin_family = AF_INET;
localHost.sin_port = htons(port);
localHost.sin_addr.s_addr = INADDR_ANY;
if (lwip_bind(_sock_fd, (const struct sockaddr *) &localHost, sizeof(localHost)) < 0) {
close();
return -1;
}
return 0;
}
int TCPSocketServer::listen(int max) {
if (_sock_fd < 0)
return -1;
if (lwip_listen(_sock_fd, max) < 0) {
close();
return -1;
}
return 0;
}
int TCPSocketServer::accept(TCPSocketConnection& connection) {
if (_sock_fd < 0)
return -1;
if (!_blocking) {
TimeInterval timeout(_timeout);
if (wait_readable(timeout) != 0)
return -1;
}
connection.reset_address();
socklen_t newSockRemoteHostLen = sizeof(connection._remoteHost);
int fd = lwip_accept(_sock_fd, (struct sockaddr*) &connection._remoteHost, &newSockRemoteHostLen);
if (fd < 0)
return -1; //Accept failed
connection._sock_fd = fd;
connection._is_connected = true;
return 0;
}

View file

@ -0,0 +1,52 @@
/* Copyright (C) 2012 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef TCPSOCKETSERVER_H
#define TCPSOCKETSERVER_H
#include "Socket/Socket.h"
#include "TCPSocketConnection.h"
/** TCP Server.
*/
class TCPSocketServer : public Socket {
public:
/** Instantiate a TCP Server.
*/
TCPSocketServer();
/** Bind a socket to a specific port.
\param port The port to listen for incoming connections on.
\return 0 on success, -1 on failure.
*/
int bind(int port);
/** Start listening for incoming connections.
\param backlog number of pending connections that can be queued up at any
one time [Default: 1].
\return 0 on success, -1 on failure.
*/
int listen(int backlog=1);
/** Accept a new connection.
\param connection A TCPSocketConnection instance that will handle the incoming connection.
\return 0 on success, -1 on failure.
*/
int accept(TCPSocketConnection& connection);
};
#endif

View file

@ -0,0 +1,94 @@
/* Copyright (C) 2012 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "Socket/UDPSocket.h"
#include <cstring>
using std::memset;
UDPSocket::UDPSocket() {
}
int UDPSocket::init(void) {
return init_socket(SOCK_DGRAM);
}
// Server initialization
int UDPSocket::bind(int port) {
if (init_socket(SOCK_DGRAM) < 0)
return -1;
struct sockaddr_in localHost;
std::memset(&localHost, 0, sizeof(localHost));
localHost.sin_family = AF_INET;
localHost.sin_port = htons(port);
localHost.sin_addr.s_addr = INADDR_ANY;
if (lwip_bind(_sock_fd, (const struct sockaddr *) &localHost, sizeof(localHost)) < 0) {
close();
return -1;
}
return 0;
}
int UDPSocket::join_multicast_group(const char* address) {
struct ip_mreq mreq;
// Set up group address
mreq.imr_multiaddr.s_addr = inet_addr(address);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
return set_option(IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
}
int UDPSocket::set_broadcasting(bool broadcast) {
int option = (broadcast) ? (1) : (0);
return set_option(SOL_SOCKET, SO_BROADCAST, &option, sizeof(option));
}
// -1 if unsuccessful, else number of bytes written
int UDPSocket::sendTo(Endpoint &remote, char *packet, int length) {
if (_sock_fd < 0)
return -1;
if (!_blocking) {
TimeInterval timeout(_timeout);
if (wait_writable(timeout) != 0)
return 0;
}
return lwip_sendto(_sock_fd, packet, length, 0, (const struct sockaddr *) &remote._remoteHost, sizeof(remote._remoteHost));
}
// -1 if unsuccessful, else number of bytes received
int UDPSocket::receiveFrom(Endpoint &remote, char *buffer, int length) {
if (_sock_fd < 0)
return -1;
if (!_blocking) {
TimeInterval timeout(_timeout);
if (wait_readable(timeout) != 0)
return 0;
}
remote.reset_address();
socklen_t remoteHostLen = sizeof(remote._remoteHost);
return lwip_recvfrom(_sock_fd, buffer, length, 0, (struct sockaddr*) &remote._remoteHost, &remoteHostLen);
}

View file

@ -0,0 +1,75 @@
/* Copyright (C) 2012 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef UDPSOCKET_H
#define UDPSOCKET_H
#include "Socket/Socket.h"
#include "Socket/Endpoint.h"
/**
UDP Socket
*/
class UDPSocket : public Socket {
public:
/** Instantiate an UDP Socket.
*/
UDPSocket();
/** Init the UDP Client Socket without binding it to any specific port
\return 0 on success, -1 on failure.
*/
int init(void);
/** Bind a UDP Server Socket to a specific port
\param port The port to listen for incoming connections on
\return 0 on success, -1 on failure.
*/
int bind(int port);
/** Join the multicast group at the given address
\param address The address of the multicast group
\return 0 on success, -1 on failure.
*/
int join_multicast_group(const char* address);
/** Set the socket in broadcasting mode
\return 0 on success, -1 on failure.
*/
int set_broadcasting(bool broadcast=true);
/** Send a packet to a remote endpoint
\param remote The remote endpoint
\param packet The packet to be sent
\param length The length of the packet to be sent
\return the number of written bytes on success (>=0) or -1 on failure
*/
int sendTo(Endpoint &remote, char *packet, int length);
/** Receive a packet from a remote endpoint
\param remote The remote endpoint
\param buffer The buffer for storing the incoming packet data. If a packet
is too long to fit in the supplied buffer, excess bytes are discarded
\param length The length of the buffer
\return the number of received bytes on success (>=0) or -1 on failure
*/
int receiveFrom(Endpoint &remote, char *buffer, int length);
};
#endif