mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			New feature: send/recv message implementation added to network stack
							parent
							
								
									539d1c784f
								
							
						
					
					
						commit
						bdfd98e764
					
				| 
						 | 
				
			
			@ -88,6 +88,21 @@ protected: // NetworkStack
 | 
			
		|||
 | 
			
		||||
    virtual void socket_attach(nsapi_socket_t handle, void (*callback)(void *), void *data);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    nsapi_size_or_error_t socket_sendmsg(nsapi_socket_t handle, const SocketAddress &address,
 | 
			
		||||
                                         const void *data, nsapi_size_t size,
 | 
			
		||||
                                         nsapi_msghdr_t *control, nsapi_size_t control_size) override
 | 
			
		||||
    {
 | 
			
		||||
        return NSAPI_ERROR_UNSUPPORTED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    nsapi_size_or_error_t socket_recvmsg(nsapi_socket_t handle, SocketAddress *address,
 | 
			
		||||
                                         void *data, nsapi_size_t size,
 | 
			
		||||
                                         nsapi_msghdr_t *control, nsapi_size_t control_size) override
 | 
			
		||||
    {
 | 
			
		||||
        return NSAPI_ERROR_UNSUPPORTED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    class CellularSocket {
 | 
			
		||||
    public:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -163,6 +163,9 @@ public:
 | 
			
		|||
        static void netif_status_irq(struct netif *netif);
 | 
			
		||||
        static Interface *our_if_from_netif(struct netif *netif);
 | 
			
		||||
        static void delete_interface(OnboardNetworkStack::Interface **interface_out);
 | 
			
		||||
        NetworkInterface *network_if_from_netif_id(int id);
 | 
			
		||||
        int netif_id_from_network_if(NetworkInterface *userInterface);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if LWIP_ETHERNET
 | 
			
		||||
        static err_t emac_low_level_output(struct netif *netif, struct pbuf *p);
 | 
			
		||||
| 
						 | 
				
			
			@ -222,6 +225,8 @@ public:
 | 
			
		|||
            void *hw; /**< alternative implementation pointer - used for PPP */
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        NetworkInterface *user_network_interface;
 | 
			
		||||
 | 
			
		||||
        mbed_rtos_storage_semaphore_t remove_interface_sem;
 | 
			
		||||
        osSemaphoreId_t remove_interface;
 | 
			
		||||
        mbed_rtos_storage_semaphore_t linked_sem;
 | 
			
		||||
| 
						 | 
				
			
			@ -265,7 +270,7 @@ public:
 | 
			
		|||
     * @param[out] interface_out    pointer to stack interface object controlling the EMAC
 | 
			
		||||
     * @return                      NSAPI_ERROR_OK on success, or error code
 | 
			
		||||
     */
 | 
			
		||||
    nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out) override;
 | 
			
		||||
    nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out, NetworkInterface *user_network_interface = NULL) override;
 | 
			
		||||
 | 
			
		||||
    /** Register a network interface with the IP stack
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			@ -450,6 +455,27 @@ protected:
 | 
			
		|||
    nsapi_size_or_error_t socket_send(nsapi_socket_t handle,
 | 
			
		||||
                                      const void *data, nsapi_size_t size) override;
 | 
			
		||||
 | 
			
		||||
    /** Send a packet with ancillary data over a UDP socket
 | 
			
		||||
      *
 | 
			
		||||
      *  Sends data to the specified address. Returns the number of bytes
 | 
			
		||||
      *  sent from the buffer.
 | 
			
		||||
      *
 | 
			
		||||
      *  This call is non-blocking. If sendto would block,
 | 
			
		||||
      *  NSAPI_ERROR_WOULD_BLOCK is returned immediately.
 | 
			
		||||
      *
 | 
			
		||||
      *  @param handle        Socket handle
 | 
			
		||||
      *  @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
 | 
			
		||||
      *  @param control       Ancillary data storage
 | 
			
		||||
      *  @param control_size  Size of the Ancillary data in bytes
 | 
			
		||||
      *  @return              Number of sent bytes on success, negative error
 | 
			
		||||
      *                       code on failure
 | 
			
		||||
      */
 | 
			
		||||
    nsapi_size_or_error_t socket_sendmsg(nsapi_socket_t handle, const SocketAddress &address,
 | 
			
		||||
                                         const void *data, nsapi_size_t size,
 | 
			
		||||
                                         nsapi_msghdr_t *control, nsapi_size_t control_size) override;
 | 
			
		||||
 | 
			
		||||
    /** Receive data over a TCP socket
 | 
			
		||||
     *
 | 
			
		||||
     *  The socket must be connected to a remote host. Returns the number of
 | 
			
		||||
| 
						 | 
				
			
			@ -493,6 +519,7 @@ protected:
 | 
			
		|||
     *  This call is non-blocking. If recvfrom would block,
 | 
			
		||||
     *  NSAPI_ERROR_WOULD_BLOCK is returned immediately.
 | 
			
		||||
     *
 | 
			
		||||
     *  It uses socket_recvmsg with  zero ancillary data.
 | 
			
		||||
     *  @param handle   Socket handle
 | 
			
		||||
     *  @param address  Destination for the source address or NULL
 | 
			
		||||
     *  @param buffer   Destination buffer for data received from the host
 | 
			
		||||
| 
						 | 
				
			
			@ -503,6 +530,27 @@ protected:
 | 
			
		|||
    nsapi_size_or_error_t socket_recvfrom(nsapi_socket_t handle, SocketAddress *address,
 | 
			
		||||
                                          void *buffer, nsapi_size_t size) override;
 | 
			
		||||
 | 
			
		||||
    /** Receive a packet with ancillary data over a UDP socket
 | 
			
		||||
    *
 | 
			
		||||
    *  Receives data and stores the source address in address if address
 | 
			
		||||
    *  is not NULL. Returns the number of bytes received into the buffer.
 | 
			
		||||
    *
 | 
			
		||||
    *  This call is non-blocking. If recvfrom would block,
 | 
			
		||||
    *  NSAPI_ERROR_WOULD_BLOCK is returned immediately.
 | 
			
		||||
    *
 | 
			
		||||
    *  @param handle   Socket handle
 | 
			
		||||
    *  @param address  Destination for the source address or NULL
 | 
			
		||||
    *  @param buffer   Destination buffer for data received from the host
 | 
			
		||||
    *  @param size     Size of the buffer in bytes
 | 
			
		||||
    *  @param control     Ancillary data storage
 | 
			
		||||
    *  @param control_size   Size of the Ancillary data in bytes
 | 
			
		||||
    *  @return         Number of received bytes on success, negative error
 | 
			
		||||
    *                  code on failure
 | 
			
		||||
    */
 | 
			
		||||
    nsapi_size_or_error_t socket_recvmsg(nsapi_socket_t handle, SocketAddress *address,
 | 
			
		||||
                                         void *data, nsapi_size_t size,
 | 
			
		||||
                                         nsapi_msghdr_t *control, nsapi_size_t control_size) override;
 | 
			
		||||
 | 
			
		||||
    /** Register a callback on state change of the socket
 | 
			
		||||
     *
 | 
			
		||||
     *  The specified callback will be called on state changes such as when
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -311,6 +311,9 @@
 | 
			
		|||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// FIXME: Add compile time configuration and define conditionaly
 | 
			
		||||
#define LWIP_NETBUF_RECVINFO            MBED_CONF_LWIP_NETBUF_RECVINFO_ENABLED
 | 
			
		||||
 | 
			
		||||
// Make sure we default these to off, so
 | 
			
		||||
// LWIP doesn't default to on
 | 
			
		||||
#ifndef LWIP_ARP
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,7 +46,7 @@
 | 
			
		|||
#define LWIP_NETCONN                    !NO_SYS
 | 
			
		||||
#define LWIP_SOCKET                     !NO_SYS
 | 
			
		||||
#define LWIP_NETCONN_FULLDUPLEX         LWIP_SOCKET
 | 
			
		||||
#define LWIP_NETBUF_RECVINFO            1
 | 
			
		||||
#define LWIP_NETBUF_RECVINFO            MBED_CONF_NETBUF_RECVINFO_ENABLED
 | 
			
		||||
#define LWIP_HAVE_LOOPIF                1
 | 
			
		||||
#define TCPIP_THREAD_TEST
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,6 +42,28 @@
 | 
			
		|||
 | 
			
		||||
LWIP::Interface *LWIP::Interface::list;
 | 
			
		||||
 | 
			
		||||
NetworkInterface *LWIP::Interface::network_if_from_netif_id(int id)
 | 
			
		||||
{
 | 
			
		||||
    for (Interface *interface = list; interface; interface = interface->next) {
 | 
			
		||||
        if (id == netif_get_index(&interface->netif)) {
 | 
			
		||||
            return interface->user_network_interface;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int LWIP::Interface::netif_id_from_network_if(NetworkInterface *userInterface)
 | 
			
		||||
{
 | 
			
		||||
    if (userInterface != NULL) {
 | 
			
		||||
        for (Interface *interface = list; interface; interface = interface->next) {
 | 
			
		||||
            if (userInterface == interface->user_network_interface) {
 | 
			
		||||
                return netif_get_index(&interface->netif);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LWIP::Interface *LWIP::Interface::our_if_from_netif(struct netif *netif)
 | 
			
		||||
{
 | 
			
		||||
    for (Interface *interface = list; interface; interface = interface->next) {
 | 
			
		||||
| 
						 | 
				
			
			@ -408,7 +430,7 @@ LWIP::Interface::Interface() :
 | 
			
		|||
    list = this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_error_t LWIP::add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out)
 | 
			
		||||
nsapi_error_t LWIP::add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out, NetworkInterface *user_network_interface)
 | 
			
		||||
{
 | 
			
		||||
#if LWIP_ETHERNET
 | 
			
		||||
    Interface *interface = new (std::nothrow) Interface();
 | 
			
		||||
| 
						 | 
				
			
			@ -431,7 +453,7 @@ nsapi_error_t LWIP::add_ethernet_interface(EMAC &emac, bool default_if, OnboardN
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
    interface->netif.hwaddr_len = 6;
 | 
			
		||||
 | 
			
		||||
    interface->user_network_interface = user_network_interface;
 | 
			
		||||
    if (!netif_add(&interface->netif,
 | 
			
		||||
#if LWIP_IPV4
 | 
			
		||||
                   0, 0, 0,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,10 +15,10 @@
 | 
			
		|||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
#include "nsapi.h"
 | 
			
		||||
#include "netsocket/MsgHeader.h"
 | 
			
		||||
#include "mbed_interface.h"
 | 
			
		||||
#include "mbed_assert.h"
 | 
			
		||||
#include "Semaphore.h"
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -37,6 +37,7 @@
 | 
			
		|||
#include "lwip/raw.h"
 | 
			
		||||
#include "lwip/netif.h"
 | 
			
		||||
#include "lwip/lwip_errno.h"
 | 
			
		||||
#include "lwip/ip_addr.h"
 | 
			
		||||
#include "lwip-sys/arch/sys_arch.h"
 | 
			
		||||
 | 
			
		||||
#include "LWIPStack.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -271,7 +272,9 @@ nsapi_error_t LWIP::socket_open(nsapi_socket_t *handle, nsapi_protocol_t proto)
 | 
			
		|||
        arena_dealloc(s);
 | 
			
		||||
        return NSAPI_ERROR_NO_SOCKET;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if LWIP_NETBUF_RECVINFO
 | 
			
		||||
    s->conn->flags &= ~NETCONN_FLAG_PKTINFO;
 | 
			
		||||
#endif
 | 
			
		||||
    netconn_set_nonblocking(s->conn, true);
 | 
			
		||||
    *(struct mbed_lwip_socket **)handle = s;
 | 
			
		||||
    return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -440,41 +443,18 @@ nsapi_size_or_error_t LWIP::socket_recv(nsapi_socket_t handle, void *data, nsapi
 | 
			
		|||
 | 
			
		||||
nsapi_size_or_error_t LWIP::socket_sendto(nsapi_socket_t handle, const SocketAddress &address, const void *data, nsapi_size_t size)
 | 
			
		||||
{
 | 
			
		||||
    struct mbed_lwip_socket *s = (struct mbed_lwip_socket *)handle;
 | 
			
		||||
    ip_addr_t ip_addr;
 | 
			
		||||
 | 
			
		||||
    nsapi_addr_t addr = address.get_addr();
 | 
			
		||||
    if (!convert_mbed_addr_to_lwip(&ip_addr, &addr)) {
 | 
			
		||||
        return NSAPI_ERROR_PARAMETER;
 | 
			
		||||
    }
 | 
			
		||||
    struct netif *netif_ = netif_get_by_index(s->conn->pcb.ip->netif_idx);
 | 
			
		||||
    if (!netif_) {
 | 
			
		||||
        netif_ = &default_interface->netif;
 | 
			
		||||
    }
 | 
			
		||||
    if (netif_) {
 | 
			
		||||
        if ((addr.version == NSAPI_IPv4 && !get_ipv4_addr(netif_)) ||
 | 
			
		||||
                (addr.version == NSAPI_IPv6 && !get_ipv6_addr(netif_) && !get_ipv6_link_local_addr(netif_))) {
 | 
			
		||||
            return NSAPI_ERROR_PARAMETER;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    struct netbuf *buf = netbuf_new();
 | 
			
		||||
 | 
			
		||||
    err_t err = netbuf_ref(buf, data, (u16_t)size);
 | 
			
		||||
    if (err != ERR_OK) {
 | 
			
		||||
        netbuf_free(buf);
 | 
			
		||||
        return err_remap(err);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    err = netconn_sendto(s->conn, buf, &ip_addr, address.get_port());
 | 
			
		||||
    netbuf_delete(buf);
 | 
			
		||||
    if (err != ERR_OK) {
 | 
			
		||||
        return err_remap(err);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return size;
 | 
			
		||||
    return socket_sendmsg(handle, address, data, size, NULL, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_size_or_error_t LWIP::socket_recvfrom(nsapi_socket_t handle, SocketAddress *address, void *data, nsapi_size_t size)
 | 
			
		||||
{
 | 
			
		||||
    return socket_recvmsg(handle, address, data, size, NULL, 0);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_size_or_error_t LWIP::socket_recvmsg(nsapi_socket_t handle, SocketAddress *address,
 | 
			
		||||
                                           void *data, nsapi_size_t size,
 | 
			
		||||
                                           nsapi_msghdr_t *control, nsapi_size_t control_size)
 | 
			
		||||
{
 | 
			
		||||
    struct mbed_lwip_socket *s = (struct mbed_lwip_socket *)handle;
 | 
			
		||||
    struct netbuf *buf;
 | 
			
		||||
| 
						 | 
				
			
			@ -490,13 +470,116 @@ nsapi_size_or_error_t LWIP::socket_recvfrom(nsapi_socket_t handle, SocketAddress
 | 
			
		|||
        address->set_addr(addr);
 | 
			
		||||
        address->set_port(netbuf_fromport(buf));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if LWIP_NETBUF_RECVINFO
 | 
			
		||||
    if ((s->conn->flags & NETCONN_FLAG_PKTINFO) && control && control_size >= sizeof(nsapi_pktinfo_t)) {
 | 
			
		||||
        nsapi_pktinfo_t *pkt_info = reinterpret_cast<nsapi_pktinfo *>(control);
 | 
			
		||||
        memset(control, 0, control_size);
 | 
			
		||||
        // Not optimal but sufficient. It should help the caller in not iterating over
 | 
			
		||||
        // the control data structure
 | 
			
		||||
        control->len = control_size;
 | 
			
		||||
        control->level = NSAPI_SOCKET;
 | 
			
		||||
        control->type = NSAPI_PKTINFO;
 | 
			
		||||
        // retrieve the destination
 | 
			
		||||
        convert_lwip_addr_to_mbed(&pkt_info->ipi_addr, netbuf_destaddr(buf));
 | 
			
		||||
        // retrieve the interface id
 | 
			
		||||
        pkt_info->network_interface = default_interface->network_if_from_netif_id(buf->p->if_idx);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    u16_t recv = netbuf_copy(buf, data, (u16_t)size);
 | 
			
		||||
    netbuf_delete(buf);
 | 
			
		||||
 | 
			
		||||
    return recv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_size_or_error_t LWIP::socket_sendmsg(nsapi_socket_t handle, const SocketAddress &address,
 | 
			
		||||
                                           const void *data, nsapi_size_t size,
 | 
			
		||||
                                           nsapi_msghdr_t *control, nsapi_size_t control_size)
 | 
			
		||||
{
 | 
			
		||||
    struct mbed_lwip_socket *s = (struct mbed_lwip_socket *)handle;
 | 
			
		||||
    ip_addr_t ip_addr = {};
 | 
			
		||||
 | 
			
		||||
    // Used for backup the bound address if the packet must be sent from a specific address,
 | 
			
		||||
    ip_addr_t bound_addr = {};
 | 
			
		||||
    ip_addr_t src_addr = {};
 | 
			
		||||
 | 
			
		||||
    nsapi_pktinfo_t *pkt_info = nullptr;
 | 
			
		||||
 | 
			
		||||
    nsapi_addr_t addr = address.get_addr();
 | 
			
		||||
    if (!convert_mbed_addr_to_lwip(&ip_addr, &addr)) {
 | 
			
		||||
        return NSAPI_ERROR_PARAMETER;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // We try to extract the pktinfo from the header
 | 
			
		||||
 | 
			
		||||
    if (control) {
 | 
			
		||||
        MsgHeaderIterator it(control, control_size);
 | 
			
		||||
        while (it.has_next()) {
 | 
			
		||||
            auto *hdr = it.next();
 | 
			
		||||
            if (hdr->level == NSAPI_SOCKET && hdr->type == NSAPI_PKTINFO) {
 | 
			
		||||
                pkt_info = reinterpret_cast<nsapi_pktinfo_t *>(hdr);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (pkt_info) {
 | 
			
		||||
        if (!convert_mbed_addr_to_lwip(&src_addr, &pkt_info->ipi_addr)) {
 | 
			
		||||
            return NSAPI_ERROR_PARAMETER;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct netif *netif_ = nullptr;
 | 
			
		||||
 | 
			
		||||
    if (pkt_info) {
 | 
			
		||||
        int index = default_interface->netif_id_from_network_if((NetworkInterface *)pkt_info->network_interface);
 | 
			
		||||
        netif_ = netif_get_by_index(index);
 | 
			
		||||
    } else {
 | 
			
		||||
        netif_ = netif_get_by_index(s->conn->pcb.ip->netif_idx);
 | 
			
		||||
    }
 | 
			
		||||
    if (!netif_) {
 | 
			
		||||
        netif_ = &default_interface->netif;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (netif_) {
 | 
			
		||||
        if ((addr.version == NSAPI_IPv4 && !get_ipv4_addr(netif_)) ||
 | 
			
		||||
                (addr.version == NSAPI_IPv6 && !get_ipv6_addr(netif_) && !get_ipv6_link_local_addr(netif_))) {
 | 
			
		||||
            return NSAPI_ERROR_PARAMETER;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct netbuf *buf = netbuf_new();
 | 
			
		||||
 | 
			
		||||
    err_t err = netbuf_ref(buf, data, (u16_t)size);
 | 
			
		||||
    if (err != ERR_OK) {
 | 
			
		||||
        netbuf_free(buf);
 | 
			
		||||
        return err_remap(err);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // handle src destination if required
 | 
			
		||||
    if (pkt_info) {
 | 
			
		||||
        // Backup the bound address
 | 
			
		||||
        ip_addr_copy(bound_addr, s->conn->pcb.udp->local_ip);
 | 
			
		||||
        // replace it with the source address
 | 
			
		||||
        if (!ip_addr_isany(&src_addr)) {
 | 
			
		||||
            ip_addr_copy(s->conn->pcb.udp->local_ip, src_addr);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    err = netconn_sendto(s->conn, buf, &ip_addr, address.get_port());
 | 
			
		||||
 | 
			
		||||
    if (pkt_info) {
 | 
			
		||||
        // restore bound address
 | 
			
		||||
        ip_addr_copy(s->conn->pcb.udp->local_ip, bound_addr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    netbuf_delete(buf);
 | 
			
		||||
    if (err != ERR_OK) {
 | 
			
		||||
        return err_remap(err);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int32_t LWIP::find_multicast_member(const struct mbed_lwip_socket *s, const nsapi_ip_mreq_t *imr)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t count = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -687,6 +770,19 @@ nsapi_error_t LWIP::setsockopt(nsapi_socket_t handle, int level, int optname, co
 | 
			
		|||
            }
 | 
			
		||||
            s->conn->pcb.ip->tos = (u8_t)(*(const int *)optval);
 | 
			
		||||
            return 0;
 | 
			
		||||
 | 
			
		||||
        case NSAPI_PKTINFO:
 | 
			
		||||
#if LWIP_NETBUF_RECVINFO
 | 
			
		||||
            if (optlen != sizeof(int)) {
 | 
			
		||||
                return NSAPI_ERROR_UNSUPPORTED;
 | 
			
		||||
            }
 | 
			
		||||
            if (*(const int *)optval) {
 | 
			
		||||
                s->conn->flags |= NETCONN_FLAG_PKTINFO;
 | 
			
		||||
            } else {
 | 
			
		||||
                s->conn->flags &= ~NETCONN_FLAG_PKTINFO;
 | 
			
		||||
            }
 | 
			
		||||
            return 0;
 | 
			
		||||
#endif
 | 
			
		||||
        default:
 | 
			
		||||
            return NSAPI_ERROR_UNSUPPORTED;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,11 +40,11 @@ public:
 | 
			
		|||
    class PPPInterface;
 | 
			
		||||
 | 
			
		||||
    /* Implement OnboardNetworkStack method */
 | 
			
		||||
    nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out) override;
 | 
			
		||||
    nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out, const uint8_t *mac_addr) override;
 | 
			
		||||
    nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out, NetworkInterface *user_network_interface = NULL) override;
 | 
			
		||||
    nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out, const uint8_t *mac_addr, NetworkInterface *user_network_interface = NULL) override;
 | 
			
		||||
 | 
			
		||||
    /* Local variant with stronger typing and manual address specification */
 | 
			
		||||
    nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, Nanostack::EthernetInterface **interface_out, const uint8_t *mac_addr = NULL);
 | 
			
		||||
    nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, Nanostack::EthernetInterface **interface_out, const uint8_t *mac_addr = NULL, NetworkInterface *user_network_interface = NULL);
 | 
			
		||||
 | 
			
		||||
    nsapi_error_t add_ppp_interface(PPP &ppp, bool default_if, OnboardNetworkStack::Interface **interface_out) override;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -302,6 +302,21 @@ protected:
 | 
			
		|||
     */
 | 
			
		||||
    nsapi_error_t getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen) override;
 | 
			
		||||
 | 
			
		||||
    // FIXME: Implement
 | 
			
		||||
    nsapi_size_or_error_t socket_sendmsg(nsapi_socket_t handle, const SocketAddress &address,
 | 
			
		||||
                                         const void *data, nsapi_size_t size,
 | 
			
		||||
                                         nsapi_msghdr_t *control, nsapi_size_t control_size) override
 | 
			
		||||
    {
 | 
			
		||||
        return NSAPI_ERROR_UNSUPPORTED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    nsapi_size_or_error_t socket_recvmsg(nsapi_socket_t handle, SocketAddress *address,
 | 
			
		||||
                                         void *data, nsapi_size_t size,
 | 
			
		||||
                                         nsapi_msghdr_t *control, nsapi_size_t control_size) override
 | 
			
		||||
    {
 | 
			
		||||
        return NSAPI_ERROR_UNSUPPORTED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    /** Call in callback
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -191,7 +191,7 @@ void EMACPhy::set_mac_address(uint8_t *mac)
 | 
			
		|||
    memcpy(mac_addr, mac, sizeof mac_addr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, Nanostack::EthernetInterface **interface_out, const uint8_t *mac_addr)
 | 
			
		||||
nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, Nanostack::EthernetInterface **interface_out, const uint8_t *mac_addr, NetworkInterface *user_network_interface)
 | 
			
		||||
{
 | 
			
		||||
    if (single_phy) {
 | 
			
		||||
        return NSAPI_ERROR_DEVICE_ERROR;
 | 
			
		||||
| 
						 | 
				
			
			@ -224,7 +224,7 @@ nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, Nan
 | 
			
		|||
    return NSAPI_ERROR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out, const uint8_t *mac_addr)
 | 
			
		||||
nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out, const uint8_t *mac_addr, NetworkInterface *user_network_interface)
 | 
			
		||||
{
 | 
			
		||||
    Nanostack::EthernetInterface *interface;
 | 
			
		||||
    nsapi_error_t err = add_ethernet_interface(emac, default_if, &interface, mac_addr);
 | 
			
		||||
| 
						 | 
				
			
			@ -232,7 +232,7 @@ nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, Onb
 | 
			
		|||
    return err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out)
 | 
			
		||||
nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out, NetworkInterface *user_network_interface)
 | 
			
		||||
{
 | 
			
		||||
    Nanostack::EthernetInterface *interface;
 | 
			
		||||
    nsapi_error_t err = add_ethernet_interface(emac, default_if, &interface);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -133,6 +133,14 @@ public:
 | 
			
		|||
    nsapi_size_or_error_t recvfrom(SocketAddress *address,
 | 
			
		||||
                                   void *data, nsapi_size_t size) override;
 | 
			
		||||
    /// NOT APPLICABLE
 | 
			
		||||
    nsapi_size_or_error_t sendmsg(const SocketAddress &address,
 | 
			
		||||
                                  const void *data, nsapi_size_t size,
 | 
			
		||||
                                  nsapi_msghdr_t *control, nsapi_size_t control_size) override;
 | 
			
		||||
    /// NOT APPLICABLE
 | 
			
		||||
    nsapi_size_or_error_t recvmsg(SocketAddress *address,
 | 
			
		||||
                                  void *data, nsapi_size_t size,
 | 
			
		||||
                                  nsapi_msghdr_t *control, nsapi_size_t control_size) override;
 | 
			
		||||
    /// NOT APPLICABLE
 | 
			
		||||
    nsapi_error_t bind(const SocketAddress &address) override;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,6 +36,7 @@ public:
 | 
			
		|||
     *  nonblocking or times out, NSAPI_ERROR_WOULD_BLOCK is returned
 | 
			
		||||
     *  immediately.
 | 
			
		||||
     *
 | 
			
		||||
     *  It uses sendmsg with zero ancillary data
 | 
			
		||||
     *  @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.
 | 
			
		||||
| 
						 | 
				
			
			@ -60,7 +61,7 @@ public:
 | 
			
		|||
     *  are accepted.
 | 
			
		||||
     *
 | 
			
		||||
     *  @note recvfrom() is allowed write to address and data buffers even if error occurs.
 | 
			
		||||
     *
 | 
			
		||||
     *  It uses recvmsg with zero ancillary data
 | 
			
		||||
     *  @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.
 | 
			
		||||
| 
						 | 
				
			
			@ -74,6 +75,58 @@ public:
 | 
			
		|||
    nsapi_size_or_error_t recvfrom(SocketAddress *address,
 | 
			
		||||
                                   void *data, nsapi_size_t size) override;
 | 
			
		||||
 | 
			
		||||
    /** Send datagram and ancillary 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.
 | 
			
		||||
     *
 | 
			
		||||
     *  It uses sendmsg with zero ancillary data
 | 
			
		||||
     *  @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.
 | 
			
		||||
     *  @param control     Size of the buffer in bytes.
 | 
			
		||||
     *  @param control_size     Size of the buffer in bytes.
 | 
			
		||||
     *  @retval         NSAPI_ERROR_NO_SOCKET in case socket was not created correctly.
 | 
			
		||||
     *  @retval         NSAPI_ERROR_WOULD_BLOCK in case non-blocking mode is enabled
 | 
			
		||||
     *                  and send cannot be performed immediately.
 | 
			
		||||
     *  @retval         int Other negative error codes for stack-related failures.
 | 
			
		||||
     *                  See \ref NetworkStack::socket_send.
 | 
			
		||||
     */
 | 
			
		||||
    nsapi_size_or_error_t sendmsg(const SocketAddress &address,
 | 
			
		||||
                                  const void *data, nsapi_size_t size,
 | 
			
		||||
                                  nsapi_msghdr_t *control, nsapi_size_t control_size) override;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /** Receive a datagram with ancillary data 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.
 | 
			
		||||
    *  Ancillary data  is stored in msghdr struct
 | 
			
		||||
    *  @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 recvmsg() 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.
 | 
			
		||||
    *  @param control     Size of the buffer in bytes.
 | 
			
		||||
    *  @param control_size     Size of the buffer in bytes.
 | 
			
		||||
    *  @retval         int Number of received bytes on success.
 | 
			
		||||
    *  @retval         NSAPI_ERROR_NO_SOCKET in case socket was not created correctly.
 | 
			
		||||
    *  @retval         NSAPI_ERROR_WOULD_BLOCK in case non-blocking mode is enabled
 | 
			
		||||
    *                  and send cannot be performed immediately.
 | 
			
		||||
    *  @retval         int Other negative error codes for stack-related failures.
 | 
			
		||||
    *                  See \ref NetworkStack::socket_recv.
 | 
			
		||||
    */
 | 
			
		||||
    nsapi_size_or_error_t recvmsg(SocketAddress *address,
 | 
			
		||||
                                  void *data, nsapi_size_t size,
 | 
			
		||||
                                  nsapi_msghdr_t *control, nsapi_size_t control_size) override;
 | 
			
		||||
 | 
			
		||||
    /** 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.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,74 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2021 ARM Limited
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * 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 MSG_HEADER_H
 | 
			
		||||
#define MSG_HEADER_H
 | 
			
		||||
 | 
			
		||||
#include "netsocket/nsapi_types.h"
 | 
			
		||||
 | 
			
		||||
struct MsgHeaderIterator {
 | 
			
		||||
    MsgHeaderIterator(nsapi_msghdr_t *hdr, nsapi_size_t size) :
 | 
			
		||||
        start(hdr),
 | 
			
		||||
        current(nullptr),
 | 
			
		||||
        size(size)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    bool has_next()
 | 
			
		||||
    {
 | 
			
		||||
        if (current == nullptr) {
 | 
			
		||||
            if (start != nullptr) {
 | 
			
		||||
                return true;
 | 
			
		||||
            } else {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (current->len < sizeof(*current)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ((reinterpret_cast<uint8_t *>(current) + current->len) >= (reinterpret_cast<uint8_t *>(start) + size)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    nsapi_msghdr_t *next()
 | 
			
		||||
    {
 | 
			
		||||
        if (!has_next()) {
 | 
			
		||||
            return nullptr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (current == nullptr) {
 | 
			
		||||
            current = start;
 | 
			
		||||
        } else {
 | 
			
		||||
            current = reinterpret_cast<nsapi_msghdr_t *>(reinterpret_cast<uint8_t *>(current) + current->len);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return current;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    nsapi_msghdr_t *start;
 | 
			
		||||
    nsapi_msghdr_t *current;
 | 
			
		||||
    nsapi_size_t size;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -395,6 +395,51 @@ protected:
 | 
			
		|||
    virtual nsapi_size_or_error_t socket_recvfrom(nsapi_socket_t handle, SocketAddress *address,
 | 
			
		||||
                                                  void *buffer, nsapi_size_t size) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Send a packet with ancillary data over a UDP socket
 | 
			
		||||
     *
 | 
			
		||||
     *  Sends data to the specified address. Returns the number of bytes
 | 
			
		||||
     *  sent from the buffer.
 | 
			
		||||
     *
 | 
			
		||||
     *  This call is non-blocking. If sendto would block,
 | 
			
		||||
     *  NSAPI_ERROR_WOULD_BLOCK is returned immediately.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param handle   Socket handle
 | 
			
		||||
     *  @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
 | 
			
		||||
     *  @param control     Storage for ancillary data
 | 
			
		||||
     *  @param control_size   Size of  ancillary data
 | 
			
		||||
     *  @return         Number of sent bytes on success, negative error
 | 
			
		||||
     *                  code on failure
 | 
			
		||||
     */
 | 
			
		||||
    virtual nsapi_size_or_error_t socket_sendmsg(nsapi_socket_t handle, const SocketAddress &address,
 | 
			
		||||
                                                 const void *data, nsapi_size_t size,
 | 
			
		||||
                                                 nsapi_msghdr_t *control, nsapi_size_t control_size) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Receive a packet with ancillary data over a UDP socket
 | 
			
		||||
     *
 | 
			
		||||
     *  Receives data and stores the source address in address if address
 | 
			
		||||
     *  is not NULL. Returns the number of bytes received into the buffer.
 | 
			
		||||
     *
 | 
			
		||||
     *  Additional information related to the message can be retrieved with
 | 
			
		||||
     *  the control data.
 | 
			
		||||
     *
 | 
			
		||||
     *  This call is non-blocking. If recvfrom would block,
 | 
			
		||||
     *  NSAPI_ERROR_WOULD_BLOCK is returned immediately.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param handle   Socket handle
 | 
			
		||||
     *  @param address  Destination for the source address or NULL
 | 
			
		||||
     *  @param buffer   Destination buffer for data received from the host
 | 
			
		||||
     *  @param size     Size of the buffer in bytes
 | 
			
		||||
     *  @param control     Storage for ancillary data
 | 
			
		||||
     *  @param control_size   Size of  ancillary data
 | 
			
		||||
     *  @return         Number of received bytes on success, negative error
 | 
			
		||||
     *                  code on failure
 | 
			
		||||
     */
 | 
			
		||||
    virtual nsapi_size_or_error_t socket_recvmsg(nsapi_socket_t handle, SocketAddress *address,
 | 
			
		||||
                                                 void *data, nsapi_size_t size,
 | 
			
		||||
                                                 nsapi_msghdr_t *control, nsapi_size_t control_size) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Register a callback on state change of the socket
 | 
			
		||||
     *
 | 
			
		||||
     *  The specified callback will be called on state changes such as when
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -160,9 +160,10 @@ public:
 | 
			
		|||
     * @param[out] interface_out    pointer to stack interface object controlling the EMAC
 | 
			
		||||
     * @return                      NSAPI_ERROR_OK on success, or error code
 | 
			
		||||
     */
 | 
			
		||||
    virtual nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, Interface **interface_out) = 0;
 | 
			
		||||
    virtual nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, Interface **interface_out, NetworkInterface *user_network_interface = NULL) = 0;
 | 
			
		||||
 | 
			
		||||
    virtual nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, Interface **interface_out, const uint8_t *mac_addr, NetworkInterface *user_network_interface = NULL)
 | 
			
		||||
 | 
			
		||||
    virtual nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, Interface **interface_out, const uint8_t *mac_addr)
 | 
			
		||||
    {
 | 
			
		||||
        return NSAPI_ERROR_UNSUPPORTED;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -157,6 +157,55 @@ public:
 | 
			
		|||
    virtual nsapi_size_or_error_t recvfrom(SocketAddress *address,
 | 
			
		||||
                                           void *data, nsapi_size_t size) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Send a message on a socket.
 | 
			
		||||
     *
 | 
			
		||||
     * The sendmsg() function sends a message through a connection-mode or connectionless-mode socket.
 | 
			
		||||
     * If the socket is a connectionless-mode socket, the message is sent to the address specified.
 | 
			
		||||
     * If the socket is a connected-mode socket, address is ignored.
 | 
			
		||||
     *
 | 
			
		||||
     * Additional control information can be passed to the stack for specific operations.
 | 
			
		||||
     *
 | 
			
		||||
     * By default, sendto blocks until data is sent. If socket is set to
 | 
			
		||||
     * non-blocking or times out, NSAPI_ERROR_WOULD_BLOCK is returned
 | 
			
		||||
     * immediately.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param address  Remote address
 | 
			
		||||
     *  @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 subclass-dependent error
 | 
			
		||||
     *                  code on failure
 | 
			
		||||
     */
 | 
			
		||||
    virtual nsapi_size_or_error_t sendmsg(const SocketAddress &address,
 | 
			
		||||
                                          const void *data, nsapi_size_t size,
 | 
			
		||||
                                          nsapi_msghdr_t *control, nsapi_size_t control_size) = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /** Receive a data from a socket
 | 
			
		||||
     *
 | 
			
		||||
     *  Receives a data and stores the source address in address if address
 | 
			
		||||
     *  is not NULL. Returns the number of bytes written into the buffer.
 | 
			
		||||
     *
 | 
			
		||||
     *  If socket is connected, only packets coming from connected peer address
 | 
			
		||||
     *  are accepted.
 | 
			
		||||
     *
 | 
			
		||||
     * Additional information related to the message can be retrieved with the control data.
 | 
			
		||||
     *
 | 
			
		||||
     *  @note recvmsg() is allowed write to address and data buffers even if error occurs.
 | 
			
		||||
     *
 | 
			
		||||
     *  By default, recvfrom blocks until a datagram is received. If socket is set to
 | 
			
		||||
     *  non-blocking or times out with no data, NSAPI_ERROR_WOULD_BLOCK
 | 
			
		||||
     *  is returned.
 | 
			
		||||
     *
 | 
			
		||||
     *  @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 subclass-dependent
 | 
			
		||||
     *                  error code on failure
 | 
			
		||||
     */
 | 
			
		||||
    virtual nsapi_size_or_error_t recvmsg(SocketAddress *address,
 | 
			
		||||
                                          void *data, nsapi_size_t size,
 | 
			
		||||
                                          nsapi_msghdr_t *control, nsapi_size_t control_size) = 0;
 | 
			
		||||
 | 
			
		||||
    /** Bind a specific address to a socket.
 | 
			
		||||
     *
 | 
			
		||||
     *  Binding a socket specifies the address and port on which to receive
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -145,6 +145,53 @@ public:
 | 
			
		|||
    nsapi_size_or_error_t recvfrom(SocketAddress *address,
 | 
			
		||||
                                   void *data, nsapi_size_t size) override;
 | 
			
		||||
 | 
			
		||||
    /** Send data on a packet with ancillary datasocket.
 | 
			
		||||
    *
 | 
			
		||||
    * TCP socket is connection oriented protocol, so address is ignored.
 | 
			
		||||
    *
 | 
			
		||||
    * By default, sendmsg blocks until data is sent. If socket is set to
 | 
			
		||||
    * non-blocking or times out, NSAPI_ERROR_WOULD_BLOCK is returned
 | 
			
		||||
    * immediately.
 | 
			
		||||
    *
 | 
			
		||||
    *  @param address  Remote address
 | 
			
		||||
    *  @param data     Buffer of data to send to the host
 | 
			
		||||
    *  @param size     Size of the buffer in bytes
 | 
			
		||||
    *  @retval         int Number of sent bytes on success
 | 
			
		||||
    *  @retval         NSAPI_ERROR_NO_SOCKET in case socket was not created correctly
 | 
			
		||||
    *  @retval         NSAPI_ERROR_WOULD_BLOCK in case non-blocking mode is enabled
 | 
			
		||||
    *                  and send cannot be performed immediately
 | 
			
		||||
    *  @retval         int Other negative error codes for stack-related failures.
 | 
			
		||||
    *                  See @ref NetworkStack::socket_send.
 | 
			
		||||
    */
 | 
			
		||||
    nsapi_size_or_error_t sendmsg(const SocketAddress &address,
 | 
			
		||||
                                  const void *data, nsapi_size_t size,
 | 
			
		||||
                                  nsapi_msghdr_t *control, nsapi_size_t control_size) override;
 | 
			
		||||
 | 
			
		||||
    /** Receive a packet with ancillary data from a socket
 | 
			
		||||
     *
 | 
			
		||||
     *  Receives a data and stores the source address in address if address
 | 
			
		||||
     *  is not NULL. Returns the number of bytes written into the buffer.
 | 
			
		||||
     *
 | 
			
		||||
     *  By default, recvmsg blocks until a data is received. If socket is set to
 | 
			
		||||
     *  non-blocking or times out with no datagram, NSAPI_ERROR_WOULD_BLOCK
 | 
			
		||||
     *  is returned.
 | 
			
		||||
     *
 | 
			
		||||
     *  @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
 | 
			
		||||
     *  @control        Pointer to the control buffer
 | 
			
		||||
     *  @control_size     Size of the control buffer in bytes
 | 
			
		||||
     *  @retval         int Number of received bytes on success
 | 
			
		||||
     *  @retval         NSAPI_ERROR_NO_SOCKET in case socket was not created correctly
 | 
			
		||||
     *  @retval         NSAPI_ERROR_WOULD_BLOCK in case non-blocking mode is enabled
 | 
			
		||||
     *                  and send cannot be performed immediately
 | 
			
		||||
     *  @retval         int Other negative error codes for stack-related failures.
 | 
			
		||||
     *                  See @ref NetworkStack::socket_recv.
 | 
			
		||||
     */
 | 
			
		||||
    nsapi_size_or_error_t recvmsg(SocketAddress *address,
 | 
			
		||||
                                  void *data, nsapi_size_t size,
 | 
			
		||||
                                  nsapi_msghdr_t *control, nsapi_size_t control_size) override;
 | 
			
		||||
 | 
			
		||||
    /** Accepts a connection on a socket.
 | 
			
		||||
     *
 | 
			
		||||
     *  The server socket must be bound and set to listen for connections.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -185,6 +185,14 @@ public:
 | 
			
		|||
    nsapi_size_or_error_t sendto(const SocketAddress &address, const void *data, nsapi_size_t size) override;
 | 
			
		||||
    nsapi_size_or_error_t recvfrom(SocketAddress *address,
 | 
			
		||||
                                   void *data, nsapi_size_t size) override;
 | 
			
		||||
 | 
			
		||||
    nsapi_size_or_error_t sendmsg(const SocketAddress &address,
 | 
			
		||||
                                  const void *data, nsapi_size_t size,
 | 
			
		||||
                                  nsapi_msghdr_t *control, nsapi_size_t control_size) override;
 | 
			
		||||
    nsapi_size_or_error_t recvmsg(SocketAddress *address,
 | 
			
		||||
                                  void *data, nsapi_size_t size,
 | 
			
		||||
                                  nsapi_msghdr_t *control, nsapi_size_t control_size) override;
 | 
			
		||||
 | 
			
		||||
    nsapi_error_t bind(const SocketAddress &address) override;
 | 
			
		||||
    void set_blocking(bool blocking) override;
 | 
			
		||||
    void set_timeout(int timeout) override;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -318,7 +318,8 @@ typedef enum nsapi_socket_option {
 | 
			
		|||
    NSAPI_LATENCY,           /*!< Read estimated latency to destination */
 | 
			
		||||
    NSAPI_STAGGER,           /*!< Read estimated stagger value to destination */
 | 
			
		||||
    NSAPI_IPTOS,             /*!< Set IP type of service to set specific precedence */
 | 
			
		||||
    NSAPI_BROADCAST          /*!< Set broadcast flag for UDP socket */
 | 
			
		||||
    NSAPI_BROADCAST,         /*!< Set broadcast flag for UDP socket */
 | 
			
		||||
    NSAPI_PKTINFO            /*!< Get additional information when using sendmsg/recvmsg */
 | 
			
		||||
} nsapi_socket_option_t;
 | 
			
		||||
 | 
			
		||||
typedef enum nsapi_tlssocket_level {
 | 
			
		||||
| 
						 | 
				
			
			@ -406,6 +407,23 @@ typedef struct nsapi_stagger_req {
 | 
			
		|||
    uint16_t stagger_rand;  /* [OUT] Randomized stagger value in seconds */
 | 
			
		||||
} nsapi_stagger_req_t;
 | 
			
		||||
 | 
			
		||||
/** nsapi_msghdr
 | 
			
		||||
 */
 | 
			
		||||
typedef struct nsapi_msghdr {
 | 
			
		||||
    nsapi_size_t len;    /* Data byte count, including header */
 | 
			
		||||
    int          level;  /* Originating protocol */
 | 
			
		||||
    int          type;   /* Protocol-specific type */
 | 
			
		||||
} nsapi_msghdr_t;
 | 
			
		||||
 | 
			
		||||
/** nsapi_pktinfo structure
 | 
			
		||||
 */
 | 
			
		||||
typedef struct nsapi_pktinfo {
 | 
			
		||||
    nsapi_msghdr_t hdr;         /* Header identifying the message control structure */
 | 
			
		||||
    nsapi_addr_t   ipi_addr;    /* Address associated with the packet */
 | 
			
		||||
    int            ipi_ifindex; /* Interface associated with the packet */
 | 
			
		||||
    void          *network_interface; /* Network interface pointer*/
 | 
			
		||||
} nsapi_pktinfo_t;
 | 
			
		||||
 | 
			
		||||
/** nsapi_stack_api structure
 | 
			
		||||
 *
 | 
			
		||||
 *  Common api structure for network stack operations. A network stack
 | 
			
		||||
| 
						 | 
				
			
			@ -644,6 +662,17 @@ typedef struct nsapi_stack_api {
 | 
			
		|||
    nsapi_size_or_error_t (*socket_recvfrom)(nsapi_stack_t *stack, nsapi_socket_t socket,
 | 
			
		||||
                                             nsapi_addr_t *addr, uint16_t *port, void *buffer, nsapi_size_t size);
 | 
			
		||||
 | 
			
		||||
    // TODO: Documentation
 | 
			
		||||
    nsapi_size_or_error_t (*socket_sendmsg)(nsapi_stack_t *stack, nsapi_socket_t socket,
 | 
			
		||||
                                            nsapi_addr_t addr, uint16_t port,
 | 
			
		||||
                                            const void *data, nsapi_size_t size,
 | 
			
		||||
                                            const nsapi_msghdr_t *control, nsapi_size_t control_size);
 | 
			
		||||
 | 
			
		||||
    nsapi_size_or_error_t (*socket_recvmsg)(nsapi_stack_t *stack, nsapi_socket_t socket,
 | 
			
		||||
                                            nsapi_addr_t *addr, uint16_t *port,
 | 
			
		||||
                                            void *data, nsapi_size_t size,
 | 
			
		||||
                                            nsapi_msghdr_t *control, nsapi_size_t control_size);
 | 
			
		||||
 | 
			
		||||
    /** Register a callback on state change of the socket
 | 
			
		||||
     *
 | 
			
		||||
     *  The specified callback will be called on state changes such as when
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -244,12 +244,26 @@ nsapi_size_or_error_t CellularNonIPSocket::sendto(const SocketAddress &address,
 | 
			
		|||
{
 | 
			
		||||
    return NSAPI_ERROR_UNSUPPORTED;
 | 
			
		||||
}
 | 
			
		||||
nsapi_size_or_error_t CellularNonIPSocket::sendmsg(const SocketAddress &address,
 | 
			
		||||
                                                   const void *data, nsapi_size_t size,
 | 
			
		||||
                                                   nsapi_msghdr_t *control, nsapi_size_t control_size)
 | 
			
		||||
{
 | 
			
		||||
    return NSAPI_ERROR_UNSUPPORTED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_size_or_error_t CellularNonIPSocket::recvfrom(SocketAddress *address,
 | 
			
		||||
                                                    void *data, nsapi_size_t size)
 | 
			
		||||
{
 | 
			
		||||
    return NSAPI_ERROR_UNSUPPORTED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_size_or_error_t CellularNonIPSocket::recvmsg(SocketAddress *address,
 | 
			
		||||
                                                   void *data, nsapi_size_t size,
 | 
			
		||||
                                                   nsapi_msghdr_t *control, nsapi_size_t control_size)
 | 
			
		||||
{
 | 
			
		||||
    return NSAPI_ERROR_UNSUPPORTED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_error_t CellularNonIPSocket::setsockopt(int level, int optname, const void *optval, unsigned optlen)
 | 
			
		||||
{
 | 
			
		||||
    return NSAPI_ERROR_UNSUPPORTED;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,14 +55,14 @@ nsapi_error_t EMACInterface::connect()
 | 
			
		|||
        nsapi_error_t err = NSAPI_ERROR_UNSUPPORTED;
 | 
			
		||||
 | 
			
		||||
        if (_hw_mac_addr_set) {
 | 
			
		||||
            err = _stack.add_ethernet_interface(_emac, true, &_interface, _hw_mac_addr);
 | 
			
		||||
            err = _stack.add_ethernet_interface(_emac, true, &_interface, _hw_mac_addr, this);
 | 
			
		||||
            if (err == NSAPI_ERROR_UNSUPPORTED) {
 | 
			
		||||
                tr_error("Failed to set user MAC address");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (err == NSAPI_ERROR_UNSUPPORTED) {
 | 
			
		||||
            err = _stack.add_ethernet_interface(_emac, true, &_interface);
 | 
			
		||||
            err = _stack.add_ethernet_interface(_emac, true, &_interface, this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (err != NSAPI_ERROR_OK) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,7 +27,7 @@ nsapi_error_t InternetDatagramSocket::connect(const SocketAddress &address)
 | 
			
		|||
    return NSAPI_ERROR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_size_or_error_t InternetDatagramSocket::sendto(const SocketAddress &address, const void *data, nsapi_size_t size)
 | 
			
		||||
nsapi_size_or_error_t InternetDatagramSocket::sendmsg(const SocketAddress &address, const void *data, nsapi_size_t size, nsapi_msghdr_t *control, nsapi_size_t control_size)
 | 
			
		||||
{
 | 
			
		||||
    _lock.lock();
 | 
			
		||||
    nsapi_size_or_error_t ret;
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +44,7 @@ nsapi_size_or_error_t InternetDatagramSocket::sendto(const SocketAddress &addres
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        core_util_atomic_flag_clear(&_pending);
 | 
			
		||||
        nsapi_size_or_error_t sent = _stack->socket_sendto(_socket, address, data, size);
 | 
			
		||||
        nsapi_size_or_error_t sent = _stack->socket_sendmsg(_socket, address, data, size, control, control_size);
 | 
			
		||||
        if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != sent)) {
 | 
			
		||||
            _socket_stats.stats_update_sent_bytes(this, sent);
 | 
			
		||||
            ret = sent;
 | 
			
		||||
| 
						 | 
				
			
			@ -74,6 +74,12 @@ nsapi_size_or_error_t InternetDatagramSocket::sendto(const SocketAddress &addres
 | 
			
		|||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_size_or_error_t InternetDatagramSocket::sendto(const SocketAddress &address, const void *data, nsapi_size_t size)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    return sendmsg(address, data, size, NULL, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_size_or_error_t InternetDatagramSocket::send(const void *data, nsapi_size_t size)
 | 
			
		||||
{
 | 
			
		||||
    if (!_remote_peer) {
 | 
			
		||||
| 
						 | 
				
			
			@ -82,7 +88,8 @@ nsapi_size_or_error_t InternetDatagramSocket::send(const void *data, nsapi_size_
 | 
			
		|||
    return sendto(_remote_peer, data, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_size_or_error_t InternetDatagramSocket::recvfrom(SocketAddress *address, void *buffer, nsapi_size_t size)
 | 
			
		||||
 | 
			
		||||
nsapi_size_or_error_t InternetDatagramSocket::recvmsg(SocketAddress *address, void *buffer, nsapi_size_t size, nsapi_msghdr_t *control, nsapi_size_t control_size)
 | 
			
		||||
{
 | 
			
		||||
    _lock.lock();
 | 
			
		||||
    nsapi_size_or_error_t ret;
 | 
			
		||||
| 
						 | 
				
			
			@ -104,7 +111,7 @@ nsapi_size_or_error_t InternetDatagramSocket::recvfrom(SocketAddress *address, v
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        core_util_atomic_flag_clear(&_pending);
 | 
			
		||||
        nsapi_size_or_error_t recv = _stack->socket_recvfrom(_socket, address, buffer, size);
 | 
			
		||||
        nsapi_size_or_error_t recv = _stack->socket_recvmsg(_socket, address, buffer, size, control, control_size);
 | 
			
		||||
 | 
			
		||||
        // Filter incomming packets using connected peer address
 | 
			
		||||
        if (recv >= 0 && _remote_peer && _remote_peer != *address) {
 | 
			
		||||
| 
						 | 
				
			
			@ -143,6 +150,11 @@ nsapi_size_or_error_t InternetDatagramSocket::recvfrom(SocketAddress *address, v
 | 
			
		|||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_size_or_error_t InternetDatagramSocket::recvfrom(SocketAddress *address, void *buffer, nsapi_size_t size)
 | 
			
		||||
{
 | 
			
		||||
    return recvmsg(address, buffer, size, NULL, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_size_or_error_t InternetDatagramSocket::recv(void *buffer, nsapi_size_t size)
 | 
			
		||||
{
 | 
			
		||||
    return recvfrom(NULL, buffer, size);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -399,6 +399,44 @@ protected:
 | 
			
		|||
        return err;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    nsapi_size_or_error_t socket_sendmsg(nsapi_socket_t socket, const SocketAddress &address, const void *data, nsapi_size_t size, nsapi_msghdr_t *control, nsapi_size_t control_size) override
 | 
			
		||||
    {
 | 
			
		||||
        if (control != NULL) {
 | 
			
		||||
            return NSAPI_ERROR_UNSUPPORTED;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!_stack_api()->socket_sendmsg) {
 | 
			
		||||
            return NSAPI_ERROR_UNSUPPORTED;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return _stack_api()->socket_sendmsg(_stack(), socket, address.get_addr(), address.get_port(), data, size, control, control_size);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    nsapi_size_or_error_t socket_recvmsg(nsapi_socket_t socket, SocketAddress *address, void *data, nsapi_size_t size, nsapi_msghdr_t *control, nsapi_size_t control_size) override
 | 
			
		||||
    {
 | 
			
		||||
        if (control != NULL) {
 | 
			
		||||
            return NSAPI_ERROR_UNSUPPORTED;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!_stack_api()->socket_recvmsg) {
 | 
			
		||||
            return NSAPI_ERROR_UNSUPPORTED;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        nsapi_addr_t addr = {NSAPI_IPv4, 0};
 | 
			
		||||
        uint16_t port = 0;
 | 
			
		||||
 | 
			
		||||
        nsapi_size_or_error_t err = _stack_api()->socket_recvmsg(_stack(), socket, &addr, &port, data, size, control, control_size);
 | 
			
		||||
 | 
			
		||||
        if (address) {
 | 
			
		||||
            address->set_addr(addr);
 | 
			
		||||
            address->set_port(port);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return err;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    void socket_attach(nsapi_socket_t socket, void (*callback)(void *), void *data) override
 | 
			
		||||
    {
 | 
			
		||||
        if (!_stack_api()->socket_attach) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -173,6 +173,17 @@ nsapi_size_or_error_t TCPSocket::sendto(const SocketAddress &address, const void
 | 
			
		|||
    return send(data, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_size_or_error_t TCPSocket::sendmsg(const SocketAddress &address,
 | 
			
		||||
                                         const void *data, nsapi_size_t size,
 | 
			
		||||
                                         nsapi_msghdr_t *control, nsapi_size_t control_size)
 | 
			
		||||
{
 | 
			
		||||
    // FIXME: Implement
 | 
			
		||||
    if (control) {
 | 
			
		||||
        return NSAPI_ERROR_UNSUPPORTED;
 | 
			
		||||
    }
 | 
			
		||||
    return sendto(address, data, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_size_or_error_t TCPSocket::recv(void *data, nsapi_size_t size)
 | 
			
		||||
{
 | 
			
		||||
    _lock.lock();
 | 
			
		||||
| 
						 | 
				
			
			@ -229,6 +240,17 @@ nsapi_size_or_error_t TCPSocket::recvfrom(SocketAddress *address, void *data, ns
 | 
			
		|||
    return recv(data, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_size_or_error_t TCPSocket::recvmsg(SocketAddress *address,
 | 
			
		||||
                                         void *data, nsapi_size_t size,
 | 
			
		||||
                                         nsapi_msghdr_t *control, nsapi_size_t control_size)
 | 
			
		||||
{
 | 
			
		||||
    // FIXME: Implement
 | 
			
		||||
    if (control) {
 | 
			
		||||
        return NSAPI_ERROR_UNSUPPORTED;
 | 
			
		||||
    }
 | 
			
		||||
    return recvfrom(address, data, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_error_t TCPSocket::listen(int backlog)
 | 
			
		||||
{
 | 
			
		||||
    _lock.lock();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -385,6 +385,13 @@ nsapi_size_or_error_t TLSSocketWrapper::sendto(const SocketAddress &, const void
 | 
			
		|||
    return send(data, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_size_or_error_t TLSSocketWrapper::sendmsg(const SocketAddress &address,
 | 
			
		||||
                                                const void *data, nsapi_size_t size,
 | 
			
		||||
                                                nsapi_msghdr_t *control, nsapi_size_t control_size)
 | 
			
		||||
{
 | 
			
		||||
    return sendto(address, data, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_size_or_error_t TLSSocketWrapper::recv(void *data, nsapi_size_t size)
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
| 
						 | 
				
			
			@ -445,6 +452,11 @@ nsapi_size_or_error_t TLSSocketWrapper::recvfrom(SocketAddress *address, void *d
 | 
			
		|||
    return recv(data, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_size_or_error_t TLSSocketWrapper::recvmsg(SocketAddress *address, void *data, nsapi_size_t size, nsapi_msghdr_t *control, nsapi_size_t control_size)
 | 
			
		||||
{
 | 
			
		||||
    return recvfrom(address, data, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TLSSocketWrapper::print_mbedtls_error(MBED_UNUSED const char *name, MBED_UNUSED int err)
 | 
			
		||||
{
 | 
			
		||||
// Avoid pulling in mbedtls_strerror when trace is not enabled
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -115,7 +115,7 @@ void EmacTestNetworkStack::socket_attach(nsapi_socket_t handle, void (*callback)
 | 
			
		|||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_error_t EmacTestNetworkStack::add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out)
 | 
			
		||||
nsapi_error_t EmacTestNetworkStack::add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out, NetworkInterface *user_network_interface)
 | 
			
		||||
{
 | 
			
		||||
    // Test network stack supports only one interface
 | 
			
		||||
    TEST_ASSERT_MESSAGE(!m_interface, "Only one interface supported!");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -148,7 +148,7 @@ public:
 | 
			
		|||
     * @param[out] interface_out    pointer to stack interface object controlling the EMAC
 | 
			
		||||
     * @return                      NSAPI_ERROR_OK on success, or error code
 | 
			
		||||
     */
 | 
			
		||||
    virtual nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out);
 | 
			
		||||
    virtual nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out, NetworkInterface *user_network_interface);
 | 
			
		||||
 | 
			
		||||
    /** Translates a hostname to an IP address with specific version
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -136,6 +136,12 @@ protected:
 | 
			
		|||
    {
 | 
			
		||||
        return return_value;
 | 
			
		||||
    };
 | 
			
		||||
    virtual nsapi_size_or_error_t socket_sendmsg(nsapi_socket_t handle, const SocketAddress &address,
 | 
			
		||||
                                                 const void *data, nsapi_size_t size,
 | 
			
		||||
                                                 nsapi_msghdr_t *control, nsapi_size_t control_size)
 | 
			
		||||
    {
 | 
			
		||||
        return return_value;
 | 
			
		||||
    };
 | 
			
		||||
    virtual nsapi_size_or_error_t socket_recvfrom(nsapi_socket_t handle, SocketAddress *address,
 | 
			
		||||
                                                  void *buffer, nsapi_size_t size)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -149,6 +155,12 @@ protected:
 | 
			
		|||
        }
 | 
			
		||||
        return return_value;
 | 
			
		||||
    };
 | 
			
		||||
    virtual nsapi_size_or_error_t socket_recvmsg(nsapi_socket_t handle, SocketAddress *address,
 | 
			
		||||
                                                 void *data, nsapi_size_t size,
 | 
			
		||||
                                                 nsapi_msghdr_t *control, nsapi_size_t control_size)
 | 
			
		||||
    {
 | 
			
		||||
        return return_value;
 | 
			
		||||
    };
 | 
			
		||||
    virtual void socket_attach(nsapi_socket_t handle, void (*callback)(void *), void *data) {};
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,6 +46,8 @@ public:
 | 
			
		|||
    MOCK_METHOD4(socket_recvfrom, nsapi_error_t(nsapi_socket_t handle, SocketAddress *address, void *data, nsapi_size_t size));
 | 
			
		||||
    MOCK_METHOD5(setsockopt, nsapi_error_t(nsapi_socket_t handle, int level, int optname, const void *optval, unsigned optlen));
 | 
			
		||||
    MOCK_METHOD5(getsockopt, nsapi_error_t(nsapi_socket_t handle, int level, int optname, const void *optval, unsigned *optlen));
 | 
			
		||||
    MOCK_METHOD6(socket_sendmsg, nsapi_error_t(nsapi_socket_t handle, SocketAddress *address, void *data, nsapi_size_t size, nsapi_msghdr_t *control, nsapi_size_t control_size));
 | 
			
		||||
    MOCK_METHOD6(socket_recvmsg, nsapi_error_t(nsapi_socket_t handle, SocketAddress *address, void *data, nsapi_size_t size, nsapi_msghdr_t *control, nsapi_size_t control_size));
 | 
			
		||||
//    MOCK_METHOD3(socket_attach, void(nsapi_socket_t handle, void (*callback)(void *), void *data));
 | 
			
		||||
    MOCK_METHOD3(add_ethernet_interface, nsapi_error_t(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out));
 | 
			
		||||
    MOCK_METHOD3(add_ppp_interface, nsapi_error_t(PPP &ppp, bool default_if, OnboardNetworkStack::Interface **interface_out));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,6 +56,16 @@ public:
 | 
			
		|||
    {
 | 
			
		||||
        return return_value;
 | 
			
		||||
    }
 | 
			
		||||
    virtual nsapi_size_or_error_t sendmsg(const SocketAddress &address,
 | 
			
		||||
                                          const void *data, nsapi_size_t size,  nsapi_msghdr_t *control, nsapi_size_t control_size)
 | 
			
		||||
    {
 | 
			
		||||
        return return_value;
 | 
			
		||||
    }
 | 
			
		||||
    virtual nsapi_size_or_error_t recvmsg(SocketAddress *address,
 | 
			
		||||
                                          void *data, nsapi_size_t size, nsapi_msghdr_t *control, nsapi_size_t control_size)
 | 
			
		||||
    {
 | 
			
		||||
        return return_value;
 | 
			
		||||
    }
 | 
			
		||||
    virtual Socket *accept(nsapi_error_t *error = NULL)
 | 
			
		||||
    {
 | 
			
		||||
        return NULL;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue