diff --git a/UNITTESTS/features/netsocket/DTLSSocket/unittest.cmake b/UNITTESTS/features/netsocket/DTLSSocket/unittest.cmake index 8b66364f37..fa43a292ee 100644 --- a/UNITTESTS/features/netsocket/DTLSSocket/unittest.cmake +++ b/UNITTESTS/features/netsocket/DTLSSocket/unittest.cmake @@ -7,6 +7,7 @@ set(unittest-sources ../features/netsocket/SocketAddress.cpp ../features/netsocket/NetworkStack.cpp ../features/netsocket/InternetSocket.cpp + ../features/netsocket/InternetDatagramSocket.cpp ../features/netsocket/UDPSocket.cpp ../features/netsocket/DTLSSocket.cpp ../features/netsocket/DTLSSocketWrapper.cpp diff --git a/UNITTESTS/features/netsocket/DTLSSocketWrapper/unittest.cmake b/UNITTESTS/features/netsocket/DTLSSocketWrapper/unittest.cmake index 5fc1e82ac1..98f011a071 100644 --- a/UNITTESTS/features/netsocket/DTLSSocketWrapper/unittest.cmake +++ b/UNITTESTS/features/netsocket/DTLSSocketWrapper/unittest.cmake @@ -7,6 +7,7 @@ set(unittest-sources ../features/netsocket/SocketAddress.cpp ../features/netsocket/NetworkStack.cpp ../features/netsocket/InternetSocket.cpp + ../features/netsocket/InternetDatagramSocket.cpp ../features/netsocket/UDPSocket.cpp ../features/netsocket/DTLSSocketWrapper.cpp ../features/netsocket/TLSSocketWrapper.cpp diff --git a/UNITTESTS/features/netsocket/UDPSocket/unittest.cmake b/UNITTESTS/features/netsocket/UDPSocket/unittest.cmake index 99a5900b24..b23122f4b3 100644 --- a/UNITTESTS/features/netsocket/UDPSocket/unittest.cmake +++ b/UNITTESTS/features/netsocket/UDPSocket/unittest.cmake @@ -7,6 +7,7 @@ set(unittest-sources ../features/netsocket/SocketAddress.cpp ../features/netsocket/NetworkStack.cpp ../features/netsocket/InternetSocket.cpp + ../features/netsocket/InternetDatagramSocket.cpp ../features/netsocket/UDPSocket.cpp ../features/frameworks/nanostack-libservice/source/libip4string/ip4tos.c ../features/frameworks/nanostack-libservice/source/libip6string/ip6tos.c diff --git a/features/lwipstack/LWIPStack.cpp b/features/lwipstack/LWIPStack.cpp index 902fc8620f..34345dc0c9 100644 --- a/features/lwipstack/LWIPStack.cpp +++ b/features/lwipstack/LWIPStack.cpp @@ -230,14 +230,28 @@ nsapi_error_t LWIP::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto) return NSAPI_ERROR_NO_SOCKET; } - enum netconn_type lwip_proto = proto == NSAPI_TCP ? NETCONN_TCP : NETCONN_UDP; + enum netconn_type netconntype; + if (proto == NSAPI_TCP) { + netconntype = NETCONN_TCP; + } else if (proto == NSAPI_UDP) { + netconntype = NETCONN_UDP; + } else if (proto == NSAPI_ICMP) { + netconntype = NETCONN_RAW; + } else { + return NSAPI_ERROR_UNSUPPORTED; + } #if LWIP_IPV6 // Enable IPv6 (or dual-stack) - lwip_proto = (enum netconn_type)(lwip_proto | NETCONN_TYPE_IPV6); + netconntype = (enum netconn_type)(netconntype | NETCONN_TYPE_IPV6); #endif - s->conn = netconn_new_with_callback(lwip_proto, &LWIP::socket_callback); + if (proto == NSAPI_ICMP) { + s->conn = netconn_new_with_proto_and_callback(NETCONN_RAW, + (u8_t)IP_PROTO_ICMP, &LWIP::socket_callback); + } else { + s->conn = netconn_new_with_callback(netconntype, &LWIP::socket_callback); + } if (!s->conn) { arena_dealloc(s); diff --git a/features/lwipstack/lwipopts.h b/features/lwipstack/lwipopts.h index 4f720de3db..0a866f391b 100644 --- a/features/lwipstack/lwipopts.h +++ b/features/lwipstack/lwipopts.h @@ -81,9 +81,7 @@ #define SYS_LIGHTWEIGHT_PROT 1 -#ifndef LWIP_RAW -#define LWIP_RAW 0 -#endif +#define LWIP_RAW MBED_CONF_LWIP_RAW_SOCKET_ENABLED #define MEMP_NUM_TCPIP_MSG_INPKT MBED_CONF_LWIP_MEMP_NUM_TCPIP_MSG_INPKT #define TCPIP_MBOX_SIZE MBED_CONF_LWIP_TCPIP_MBOX_SIZE diff --git a/features/lwipstack/mbed_lib.json b/features/lwipstack/mbed_lib.json index 0ac9c9f6b4..5ac827ac82 100644 --- a/features/lwipstack/mbed_lib.json +++ b/features/lwipstack/mbed_lib.json @@ -156,6 +156,10 @@ "num-netbuf": { "help": "Number of netbufs, each netbuf requires 64 bytes of RAM, see LWIP's opt.h for more information. Current default is 8.", "value": 8 + }, + "raw-socket-enabled": { + "help": "Enable lwip raw sockets, required for Mbed OS ICMPSocket", + "value": false } }, "target_overrides": { diff --git a/features/netsocket/ICMPSocket.cpp b/features/netsocket/ICMPSocket.cpp new file mode 100644 index 0000000000..6e564bea38 --- /dev/null +++ b/features/netsocket/ICMPSocket.cpp @@ -0,0 +1,29 @@ +/* Socket + * Copyright (c) 2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ICMPSocket.h" +#include "Timer.h" +#include "mbed_assert.h" + +ICMPSocket::ICMPSocket() +{ + _socket_stats.stats_update_proto(this, NSAPI_ICMP); +} + +nsapi_protocol_t ICMPSocket::get_proto() +{ + return NSAPI_ICMP; +} diff --git a/features/netsocket/ICMPSocket.h b/features/netsocket/ICMPSocket.h new file mode 100644 index 0000000000..6d3223d407 --- /dev/null +++ b/features/netsocket/ICMPSocket.h @@ -0,0 +1,50 @@ +/** \addtogroup netsocket */ +/** @{*/ +/* ICMPSocket + * Copyright (c) 2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ICMPSOCKET_H +#define ICMPSOCKET_H + +#include "netsocket/InternetSocket.h" +#include "netsocket/InternetDatagramSocket.h" +#include "netsocket/NetworkStack.h" +#include "netsocket/NetworkInterface.h" +#include "rtos/EventFlags.h" + + +/** ICMP socket implementation. + */ +class ICMPSocket : public InternetDatagramSocket { +public: + /** Create an uninitialized socket. + * + * @note Must call open to initialize the socket on a network stack. + */ + ICMPSocket(); + +#if !defined(DOXYGEN_ONLY) + +protected: + virtual nsapi_protocol_t get_proto(); + +#endif //!defined(DOXYGEN_ONLY) +}; + + +#endif + +/** @}*/ diff --git a/features/netsocket/InternetDatagramSocket.cpp b/features/netsocket/InternetDatagramSocket.cpp new file mode 100644 index 0000000000..7526a5e86c --- /dev/null +++ b/features/netsocket/InternetDatagramSocket.cpp @@ -0,0 +1,182 @@ +/* Socket + * Copyright (c) 2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "InternetDatagramSocket.h" +#include "Timer.h" +#include "mbed_assert.h" + +nsapi_error_t InternetDatagramSocket::connect(const SocketAddress &address) +{ + _remote_peer = address; + _socket_stats.stats_update_peer(this, _remote_peer); + _socket_stats.stats_update_socket_state(this, SOCK_CONNECTED); + return NSAPI_ERROR_OK; +} + +nsapi_size_or_error_t InternetDatagramSocket::sendto(const char *host, uint16_t port, const void *data, nsapi_size_t size) +{ + SocketAddress address; + nsapi_size_or_error_t err; + + if (!strcmp(_interface_name, "")) { + err = _stack->gethostbyname(host, &address); + } else { + err = _stack->gethostbyname(host, &address, NSAPI_UNSPEC, _interface_name); + } + + if (err) { + return NSAPI_ERROR_DNS_FAILURE; + } + + address.set_port(port); + + // sendto is thread safe + return sendto(address, data, size); +} + +nsapi_size_or_error_t InternetDatagramSocket::sendto(const SocketAddress &address, const void *data, nsapi_size_t size) +{ + _lock.lock(); + nsapi_size_or_error_t ret; + + _writers++; + if (_socket) { + _socket_stats.stats_update_socket_state(this, SOCK_OPEN); + _socket_stats.stats_update_peer(this, address); + } + while (true) { + if (!_socket) { + ret = NSAPI_ERROR_NO_SOCKET; + break; + } + + core_util_atomic_flag_clear(&_pending); + nsapi_size_or_error_t sent = _stack->socket_sendto(_socket, address, data, size); + if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != sent)) { + _socket_stats.stats_update_sent_bytes(this, sent); + ret = sent; + break; + } else { + uint32_t flag; + + // Release lock before blocking so other threads + // accessing this object aren't blocked + _lock.unlock(); + flag = _event_flag.wait_any(WRITE_FLAG, _timeout); + _lock.lock(); + + if (flag & osFlagsError) { + // Timeout break + ret = NSAPI_ERROR_WOULD_BLOCK; + break; + } + } + } + + _writers--; + if (!_socket || !_writers) { + _event_flag.set(FINISHED_FLAG); + } + _lock.unlock(); + return ret; +} + +nsapi_size_or_error_t InternetDatagramSocket::send(const void *data, nsapi_size_t size) +{ + if (!_remote_peer) { + return NSAPI_ERROR_NO_ADDRESS; + } + return sendto(_remote_peer, data, size); +} + +nsapi_size_or_error_t InternetDatagramSocket::recvfrom(SocketAddress *address, void *buffer, nsapi_size_t size) +{ + _lock.lock(); + nsapi_size_or_error_t ret; + SocketAddress ignored; + + if (!address) { + address = &ignored; + } + + _readers++; + + if (_socket) { + _socket_stats.stats_update_socket_state(this, SOCK_OPEN); + } + while (true) { + if (!_socket) { + ret = NSAPI_ERROR_NO_SOCKET; + break; + } + + core_util_atomic_flag_clear(&_pending); + nsapi_size_or_error_t recv = _stack->socket_recvfrom(_socket, address, buffer, size); + + // Filter incomming packets using connected peer address + if (recv >= 0 && _remote_peer && _remote_peer != *address) { + continue; + } + + _socket_stats.stats_update_peer(this, _remote_peer); + // Non-blocking sockets always return. Blocking only returns when success or errors other than WOULD_BLOCK + if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != recv)) { + ret = recv; + _socket_stats.stats_update_recv_bytes(this, recv); + break; + } else { + uint32_t flag; + + // Release lock before blocking so other threads + // accessing this object aren't blocked + _lock.unlock(); + flag = _event_flag.wait_any(READ_FLAG, _timeout); + _lock.lock(); + + if (flag & osFlagsError) { + // Timeout break + ret = NSAPI_ERROR_WOULD_BLOCK; + break; + } + } + } + + _readers--; + if (!_socket || !_readers) { + _event_flag.set(FINISHED_FLAG); + } + + _lock.unlock(); + return ret; +} + +nsapi_size_or_error_t InternetDatagramSocket::recv(void *buffer, nsapi_size_t size) +{ + return recvfrom(NULL, buffer, size); +} + +Socket *InternetDatagramSocket::accept(nsapi_error_t *error) +{ + if (error) { + *error = NSAPI_ERROR_UNSUPPORTED; + } + return NULL; +} + +nsapi_error_t InternetDatagramSocket::listen(int) +{ + return NSAPI_ERROR_UNSUPPORTED; +} diff --git a/features/netsocket/InternetDatagramSocket.h b/features/netsocket/InternetDatagramSocket.h new file mode 100644 index 0000000000..75c1223ba8 --- /dev/null +++ b/features/netsocket/InternetDatagramSocket.h @@ -0,0 +1,156 @@ +/** \addtogroup netsocket */ +/** @{*/ +/* InternetDatagramSocket + * Copyright (c) 2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERNETDATAGRAMSOCKET_H +#define INTERNETDATAGRAMSOCKET_H + +#include "netsocket/InternetSocket.h" +#include "netsocket/NetworkStack.h" +#include "netsocket/NetworkInterface.h" +#include "rtos/EventFlags.h" + + +/** InternetDatagramSocket socket implementation. + */ +class InternetDatagramSocket : public InternetSocket { +public: + + /** Send data to the specified host and port. + * + * By default, sendto blocks until data is sent. If socket is set to + * nonblocking or times out, NSAPI_ERROR_WOULD_BLOCK is returned + * immediately. + * + * @param host Domain name of the remote host or a dotted notation IP address. + * @param port Port of the remote host. + * @param data Buffer of data to send to the host. + * @param size Size of the buffer in bytes. + * @return Number of sent bytes on success, negative error + * code on failure. + */ + virtual nsapi_size_or_error_t sendto(const char *host, uint16_t port, + const void *data, nsapi_size_t size); + + /** Send data to the specified address. + * + * By default, sendto blocks until data is sent. If socket is set to + * nonblocking or times out, NSAPI_ERROR_WOULD_BLOCK is returned + * immediately. + * + * @param address The SocketAddress of the remote host. + * @param data Buffer of data to send to the host. + * @param size Size of the buffer in bytes. + * @return Number of sent bytes on success, negative error + * code on failure. + */ + virtual nsapi_size_or_error_t sendto(const SocketAddress &address, + const void *data, nsapi_size_t size); + + /** Receive a datagram and store the source address in address if it's not NULL. + * + * By default, recvfrom blocks until a datagram is received. If socket is set to + * nonblocking or times out with no datagram, NSAPI_ERROR_WOULD_BLOCK + * is returned. + * + * @note If the datagram is larger than the buffer, the excess data is silently discarded. + * + * @note If socket is connected, only packets coming from connected peer address + * are accepted. + * + * @note recvfrom() is allowed write to address and data buffers even if error occurs. + * + * @param address Destination for the source address or NULL. + * @param data Destination buffer for RAW data to be received from the host. + * @param size Size of the buffer in bytes. + * @return Number of received bytes on success, negative error + * code on failure. + */ + virtual nsapi_size_or_error_t recvfrom(SocketAddress *address, + void *data, nsapi_size_t size); + + /** Set the remote address for next send() call and filtering + * of incoming packets. To reset the address, zero initialized + * SocketAddress must be in the address parameter. + * + * @param address The SocketAddress of the remote host. + * @return 0 on success, negative error code on failure. + */ + virtual nsapi_error_t connect(const SocketAddress &address); + + /** Send a raw data to connected remote address. + * + * By default, send blocks until all data is sent. If socket is set to + * nonblocking or times out, a partial amount can be written. + * NSAPI_ERROR_WOULD_BLOCK is returned if no data was written. + * + * @note The socket must be connected to a remote host before send() call. + * + * @param data Buffer of data to send to the host. + * @param size Size of the buffer in bytes. + * @return Number of sent bytes on success, negative error + * code on failure. + */ + virtual nsapi_size_or_error_t send(const void *data, nsapi_size_t size); + + /** Receive data from a socket. + * + * This is equivalent to calling recvfrom(NULL, data, size). + * + * By default, recv blocks until some data is received. If socket is set to + * nonblocking or times out, NSAPI_ERROR_WOULD_BLOCK can be returned to + * indicate no data. + * + * @note recv() is allowed write to data buffer even if error occurs. + * + * @param data Pointer to buffer for data received from the host. + * @param size Size of the buffer in bytes. + * @return Number of received bytes on success, negative error + * code on failure. + */ + virtual nsapi_size_or_error_t recv(void *data, nsapi_size_t size); + + /** Not implemented for InternetDatagramSocket. + * + * @param error Not used. + * @return NSAPI_ERROR_UNSUPPORTED + */ + virtual Socket *accept(nsapi_error_t *error = NULL); + + /** Not implemented for InternetDatagramSocket. + * + * @param backlog Not used. + * @return NSAPI_ERROR_UNSUPPORTED + */ + virtual nsapi_error_t listen(int backlog = 1); +#if !defined(DOXYGEN_ONLY) + +protected: + + /** Create an uninitialized socket. + * + * @note Must call open to initialize the socket on a network stack. + */ + InternetDatagramSocket() = default; + +#endif //!defined(DOXYGEN_ONLY) +}; + + +#endif + +/** @}*/ diff --git a/features/netsocket/NetworkStack.h b/features/netsocket/NetworkStack.h index a9cc6e5bc4..a8cf469760 100644 --- a/features/netsocket/NetworkStack.h +++ b/features/netsocket/NetworkStack.h @@ -183,7 +183,7 @@ public: protected: friend class InternetSocket; - friend class UDPSocket; + friend class InternetDatagramSocket; friend class TCPSocket; friend class TCPServer; diff --git a/features/netsocket/UDPSocket.cpp b/features/netsocket/UDPSocket.cpp index d5041144dc..a21d099cfe 100644 --- a/features/netsocket/UDPSocket.cpp +++ b/features/netsocket/UDPSocket.cpp @@ -23,174 +23,7 @@ UDPSocket::UDPSocket() _socket_stats.stats_update_proto(this, NSAPI_UDP); } -UDPSocket::~UDPSocket() -{ -} - nsapi_protocol_t UDPSocket::get_proto() { return NSAPI_UDP; } - -nsapi_error_t UDPSocket::connect(const SocketAddress &address) -{ - _remote_peer = address; - _socket_stats.stats_update_peer(this, _remote_peer); - _socket_stats.stats_update_socket_state(this, SOCK_CONNECTED); - return NSAPI_ERROR_OK; -} - -nsapi_size_or_error_t UDPSocket::sendto(const char *host, uint16_t port, const void *data, nsapi_size_t size) -{ - SocketAddress address; - nsapi_size_or_error_t err; - - if (!strcmp(_interface_name, "")) { - err = _stack->gethostbyname(host, &address); - } else { - err = _stack->gethostbyname(host, &address, NSAPI_UNSPEC, _interface_name); - } - - if (err) { - return NSAPI_ERROR_DNS_FAILURE; - } - - address.set_port(port); - - // sendto is thread safe - return sendto(address, data, size); -} - -nsapi_size_or_error_t UDPSocket::sendto(const SocketAddress &address, const void *data, nsapi_size_t size) -{ - _lock.lock(); - nsapi_size_or_error_t ret; - - _writers++; - if (_socket) { - _socket_stats.stats_update_socket_state(this, SOCK_OPEN); - _socket_stats.stats_update_peer(this, address); - } - while (true) { - if (!_socket) { - ret = NSAPI_ERROR_NO_SOCKET; - break; - } - - core_util_atomic_flag_clear(&_pending); - nsapi_size_or_error_t sent = _stack->socket_sendto(_socket, address, data, size); - if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != sent)) { - _socket_stats.stats_update_sent_bytes(this, sent); - ret = sent; - break; - } else { - uint32_t flag; - - // Release lock before blocking so other threads - // accessing this object aren't blocked - _lock.unlock(); - flag = _event_flag.wait_any(WRITE_FLAG, _timeout); - _lock.lock(); - - if (flag & osFlagsError) { - // Timeout break - ret = NSAPI_ERROR_WOULD_BLOCK; - break; - } - } - } - - _writers--; - if (!_socket || !_writers) { - _event_flag.set(FINISHED_FLAG); - } - _lock.unlock(); - return ret; -} - -nsapi_size_or_error_t UDPSocket::send(const void *data, nsapi_size_t size) -{ - if (!_remote_peer) { - return NSAPI_ERROR_NO_ADDRESS; - } - return sendto(_remote_peer, data, size); -} - -nsapi_size_or_error_t UDPSocket::recvfrom(SocketAddress *address, void *buffer, nsapi_size_t size) -{ - _lock.lock(); - nsapi_size_or_error_t ret; - SocketAddress ignored; - - if (!address) { - address = &ignored; - } - - _readers++; - - if (_socket) { - _socket_stats.stats_update_socket_state(this, SOCK_OPEN); - } - while (true) { - if (!_socket) { - ret = NSAPI_ERROR_NO_SOCKET; - break; - } - - core_util_atomic_flag_clear(&_pending); - nsapi_size_or_error_t recv = _stack->socket_recvfrom(_socket, address, buffer, size); - - // Filter incomming packets using connected peer address - if (recv >= 0 && _remote_peer && _remote_peer != *address) { - continue; - } - - _socket_stats.stats_update_peer(this, _remote_peer); - // Non-blocking sockets always return. Blocking only returns when success or errors other than WOULD_BLOCK - if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != recv)) { - ret = recv; - _socket_stats.stats_update_recv_bytes(this, recv); - break; - } else { - uint32_t flag; - - // Release lock before blocking so other threads - // accessing this object aren't blocked - _lock.unlock(); - flag = _event_flag.wait_any(READ_FLAG, _timeout); - _lock.lock(); - - if (flag & osFlagsError) { - // Timeout break - ret = NSAPI_ERROR_WOULD_BLOCK; - break; - } - } - } - - _readers--; - if (!_socket || !_readers) { - _event_flag.set(FINISHED_FLAG); - } - - _lock.unlock(); - return ret; -} - -nsapi_size_or_error_t UDPSocket::recv(void *buffer, nsapi_size_t size) -{ - return recvfrom(NULL, buffer, size); -} - -Socket *UDPSocket::accept(nsapi_error_t *error) -{ - if (error) { - *error = NSAPI_ERROR_UNSUPPORTED; - } - return NULL; -} - -nsapi_error_t UDPSocket::listen(int) -{ - return NSAPI_ERROR_UNSUPPORTED; -} diff --git a/features/netsocket/UDPSocket.h b/features/netsocket/UDPSocket.h index 44025389d2..bde85b987a 100644 --- a/features/netsocket/UDPSocket.h +++ b/features/netsocket/UDPSocket.h @@ -23,12 +23,14 @@ #include "netsocket/InternetSocket.h" #include "netsocket/NetworkStack.h" #include "netsocket/NetworkInterface.h" +#include "netsocket/InternetDatagramSocket.h" #include "rtos/EventFlags.h" +#include "ICMPSocket.h" /** UDP socket implementation. */ -class UDPSocket : public InternetSocket { +class UDPSocket : public InternetDatagramSocket { public: /** Create an uninitialized socket. * @@ -53,129 +55,13 @@ public: open(stack); } - /** Destroy a socket. - * - * @note Closes socket if the socket is still open. - */ - virtual ~UDPSocket(); - - /** Send data to the specified host and port. - * - * By default, sendto blocks until data is sent. If socket is set to - * nonblocking or times out, NSAPI_ERROR_WOULD_BLOCK is returned - * immediately. - * - * @param host Domain name of the remote host or a dotted notation IP address. - * @param port Port of the remote host. - * @param data Buffer of data to send to the host. - * @param size Size of the buffer in bytes. - * @return Number of sent bytes on success, negative error - * code on failure. - */ - virtual nsapi_size_or_error_t sendto(const char *host, uint16_t port, - const void *data, nsapi_size_t size); - - /** Send data to the specified address. - * - * By default, sendto blocks until data is sent. If socket is set to - * nonblocking or times out, NSAPI_ERROR_WOULD_BLOCK is returned - * immediately. - * - * @param address The SocketAddress of the remote host. - * @param data Buffer of data to send to the host. - * @param size Size of the buffer in bytes. - * @return Number of sent bytes on success, negative error - * code on failure. - */ - virtual nsapi_size_or_error_t sendto(const SocketAddress &address, - const void *data, nsapi_size_t size); - - /** Receive a datagram and store the source address in address if it's not NULL. - * - * By default, recvfrom blocks until a datagram is received. If socket is set to - * nonblocking or times out with no datagram, NSAPI_ERROR_WOULD_BLOCK - * is returned. - * - * @note If the datagram is larger than the buffer, the excess data is silently discarded. - * - * @note If socket is connected, only packets coming from connected peer address - * are accepted. - * - * @note recvfrom() is allowed write to address and data buffers even if error occurs. - * - * @param address Destination for the source address or NULL. - * @param data Destination buffer for datagram received from the host. - * @param size Size of the buffer in bytes. - * @return Number of received bytes on success, negative error - * code on failure. - */ - virtual nsapi_size_or_error_t recvfrom(SocketAddress *address, - void *data, nsapi_size_t size); - - /** Set the remote address for next send() call and filtering - * of incoming packets. To reset the address, zero initialized - * SocketAddress must be in the address parameter. - * - * @param address The SocketAddress of the remote host. - * @return 0 on success, negative error code on failure. - */ - virtual nsapi_error_t connect(const SocketAddress &address); - - /** Send a datagram to connected remote address. - * - * By default, send blocks until all data is sent. If socket is set to - * nonblocking or times out, a partial amount can be written. - * NSAPI_ERROR_WOULD_BLOCK is returned if no data was written. - * - * @note The socket must be connected to a remote host before send() call. - * - * @param data Buffer of data to send to the host. - * @param size Size of the buffer in bytes. - * @return Number of sent bytes on success, negative error - * code on failure. - */ - virtual nsapi_size_or_error_t send(const void *data, nsapi_size_t size); - - /** Receive data from a socket. - * - * This is equivalent to calling recvfrom(NULL, data, size). - * - * If the socket is connected, only packets coming from a connected peer address - * are accepted. - * - * By default, recv blocks until some data is received. If socket is set to - * nonblocking or times out, NSAPI_ERROR_WOULD_BLOCK can be returned to - * indicate no data. - * - * @note recv() is allowed write to data buffer even if error occurs. - * - * @param data Pointer to buffer for data received from the host. - * @param size Size of the buffer in bytes. - * @return Number of received bytes on success, negative error - * code on failure. - */ - virtual nsapi_size_or_error_t recv(void *data, nsapi_size_t size); - - /** Not implemented for UDP. - * - * @param error Not used. - * @return NSAPI_ERROR_UNSUPPORTED - */ - virtual Socket *accept(nsapi_error_t *error = NULL); - - /** Not implemented for UDP. - * - * @param backlog Not used. - * @return NSAPI_ERROR_UNSUPPORTED - */ - virtual nsapi_error_t listen(int backlog = 1); - #if !defined(DOXYGEN_ONLY) protected: virtual nsapi_protocol_t get_proto(); #endif //!defined(DOXYGEN_ONLY) + }; diff --git a/features/netsocket/nsapi_types.h b/features/netsocket/nsapi_types.h index c640aa7dcd..fa0ef691da 100644 --- a/features/netsocket/nsapi_types.h +++ b/features/netsocket/nsapi_types.h @@ -215,6 +215,7 @@ typedef void *nsapi_socket_t; typedef enum nsapi_protocol { NSAPI_TCP, /*!< Socket is of TCP type */ NSAPI_UDP, /*!< Socket is of UDP type */ + NSAPI_ICMP, /*!< Socket is of ICMP type */ } nsapi_protocol_t; /** Enum of standardized stack option levels