From 2bb9d10728f6cda440cc9d943ac30f14a486bdd6 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 27 Jan 2015 11:51:24 -0600 Subject: Unix sockets: Fleshes out the recvfrom() logic --- nuttx/net/local/Make.defs | 2 +- nuttx/net/local/local.h | 146 +++++++++++++--------- nuttx/net/local/local_accept.c | 42 +------ nuttx/net/local/local_recvfrom.c | 171 ++++++++++++++++++++++++- nuttx/net/local/local_recvutils.c | 248 +++++++++++++++++++++++++++++++++++++ nuttx/net/local/local_sendpacket.c | 166 +++++++++++++++++++++++++ nuttx/net/local/local_utils.c | 205 ------------------------------ 7 files changed, 676 insertions(+), 304 deletions(-) create mode 100644 nuttx/net/local/local_recvutils.c create mode 100644 nuttx/net/local/local_sendpacket.c delete mode 100644 nuttx/net/local/local_utils.c diff --git a/nuttx/net/local/Make.defs b/nuttx/net/local/Make.defs index cd79ede8b..6b101cd7a 100644 --- a/nuttx/net/local/Make.defs +++ b/nuttx/net/local/Make.defs @@ -39,7 +39,7 @@ ifeq ($(CONFIG_NET_LOCAL),y) NET_CSRCS += local_conn.c local_connect.c local_release.c local_bind.c NET_CSRCS += local_listen.c local_accept.c local_fifo.c local_recvfrom.c -NET_CSRCS += local_send.c local_sendto.c local_utils.c +NET_CSRCS += local_send.c local_sendto.c local_sendpacket.c local_recvutils.c # Include UDP build support diff --git a/nuttx/net/local/local.h b/nuttx/net/local/local.h index dc733d15f..f9b00382f 100644 --- a/nuttx/net/local/local.h +++ b/nuttx/net/local/local.h @@ -60,11 +60,10 @@ * 2. End/Start byte * 3. 16-bit packet length (in host order) * 4. Packet data (in host order) - * 5. 16-bit checksum (in host order, includes packet length) */ -#define LOCAL_SYNC_BYTE 0x42 /* Byte in sync sequence */ -#define LOCAL_END_BYTE 0xbd /* End of sync seqence */ +#define LOCAL_SYNC_BYTE 0x42 /* Byte in sync sequence */ +#define LOCAL_END_BYTE 0xbd /* End of sync seqence */ /**************************************************************************** * Public Type Definitions @@ -140,7 +139,9 @@ struct local_conn_s sem_t lc_waitsem; /* Use to wait for a connection to be accepted */ - /* Union of fields unique to SOCK_STREAM client and servers */ + /* Union of fields unique to SOCK_STREAM client, server, and connected + * peers. + */ union { @@ -157,8 +158,16 @@ struct local_conn_s struct { - volatile int lc_result; /* Result of the connection operation */ + uint16_t lc_remaining; /* (For binary compatibility with peer) */ + volatile int lc_result; /* Result of the connection operation (client)*/ } client; + + /* Fields common to connected peers (connected or accepted) */ + + struct + { + uint16_t lc_remaining; /* Bytes remaining in the incoming stream */ + } peer; } u; }; @@ -361,6 +370,25 @@ ssize_t psock_local_sendto(FAR struct socket *psock, FAR const void *buf, size_t len, int flags, FAR const struct sockaddr *to, socklen_t tolen); +/**************************************************************************** + * Name: local_send_packet + * + * Description: + * Send a packet on the write-only FIFO. + * + * Parameters: + * fd File descriptor of write-only FIFO. + * buf Data to send + * len Length of data to send + * + * Return: + * Zero is returned on success; a negated errno value is returned on any + * failure. + * + ****************************************************************************/ + +int local_send_packet(int fd, FAR const uint8_t *buf, size_t len); + /**************************************************************************** * Function: psock_recvfrom * @@ -394,119 +422,123 @@ ssize_t psock_local_recvfrom(FAR struct socket *psock, FAR void *buf, FAR socklen_t *fromlen); /**************************************************************************** - * Name: local_create_fifos + * Name: local_fifo_read * * Description: - * Create the FIFO pair needed for a connection. + * Read a data from the read-only FIFO. + * + * Parameters: + * fd - File descriptor of read-only FIFO. + * buf - Local to store the received data + * len - Length of data to receive [in] + * Length of data actually received [out] + * + * Return: + * Zero is returned on success; a negated errno value is returned on any + * failure. If -ECONNRESET is received, then the sending side has closed + * the FIFO. In this case, the returned data may still be valid (if the + * returned len > 0). * ****************************************************************************/ -int local_create_fifos(FAR struct local_conn_s *client); +int local_fifo_read(int fd, FAR uint8_t *buf, size_t *len); /**************************************************************************** - * Name: local_destroy_fifos + * Name: local_getaddr * * Description: - * Destroy the FIFO pair used for a connection. + * Return the Unix domain address of a connection. + * + * Parameters: + * conn - The connection + * addr - The location to return the address + * addrlen - The size of the memory allocat by the caller to receive the + * address. + * + * Return: + * Zero (OK) on success; a negated errno value on failure. * ****************************************************************************/ -int local_destroy_fifos(FAR struct local_conn_s *client); +int local_getaddr(FAR struct local_conn_s *conn, FAR struct sockaddr *addr, + FAR socklen_t *addrlen); /**************************************************************************** - * Name: local_open_client_rx + * Name: local_sync * * Description: - * Only the client-side Rx FIFO. + * Read a sync bytes until the start of the packet is found. + * + * Parameters: + * fd - File descriptor of read-only FIFO. + * + * Return: + * The non-zero size of the following packet is returned on success; a + * negated errno value is returned on any failure. * ****************************************************************************/ -int local_open_client_rx(FAR struct local_conn_s *client); +int local_sync(int fd); /**************************************************************************** - * Name: local_open_client_tx + * Name: local_create_fifos * * Description: - * Only the client-side Tx FIFO. + * Create the FIFO pair needed for a connection. * ****************************************************************************/ -int local_open_client_tx(FAR struct local_conn_s *client); +int local_create_fifos(FAR struct local_conn_s *client); /**************************************************************************** - * Name: local_open_server_rx + * Name: local_destroy_fifos * * Description: - * Only the server-side Rx FIFO. + * Destroy the FIFO pair used for a connection. * ****************************************************************************/ -int local_open_server_rx(FAR struct local_conn_s *server); +int local_destroy_fifos(FAR struct local_conn_s *client); /**************************************************************************** - * Name: local_open_server_tx + * Name: local_open_client_rx * * Description: - * Only the server-side Tx FIFO. + * Only the client-side Rx FIFO. * ****************************************************************************/ -int local_open_server_tx(FAR struct local_conn_s *server); +int local_open_client_rx(FAR struct local_conn_s *client); /**************************************************************************** - * Name: local_chksum + * Name: local_open_client_tx * * Description: - * Compute a simple checksum over the packet data - * - * Parameters: - * buf Data to send - * len Length of data to send - * - * Return: - * The 16-bit checksum (including the length) + * Only the client-side Tx FIFO. * ****************************************************************************/ -uint16_t local_chksum(FAR const uint8_t *buf, size_t len); +int local_open_client_tx(FAR struct local_conn_s *client); /**************************************************************************** - * Name: local_write + * Name: local_open_server_rx * * Description: - * Write a data on the write-only FIFO. - * - * Parameters: - * fd File descriptor or write-only FIFO. - * buf Data to send - * len Length of data to send - * - * Return: - * On success, returns the number of characters sent. On error, a - * negated errno value is returned. + * Only the server-side Rx FIFO. * ****************************************************************************/ -int local_write(int fd, FAR const uint8_t *buf, size_t len); +int local_open_server_rx(FAR struct local_conn_s *server); /**************************************************************************** - * Name: local_send_packet + * Name: local_open_server_tx * * Description: - * Write a packet on the write-only FIFO. - * - * Parameters: - * fd File descriptor or write-only FIFO. - * buf Data to send - * len Length of data to send - * - * Return: - * Zero is returned on success; a negated errno value is returned on any - * failure. + * Only the server-side Tx FIFO. * ****************************************************************************/ -int local_send_packet(int fd, FAR const uint8_t *buf, size_t len); +int local_open_server_tx(FAR struct local_conn_s *server); #undef EXTERN #ifdef __cplusplus diff --git a/nuttx/net/local/local_accept.c b/nuttx/net/local/local_accept.c index b97ebc6dd..1b6cbb9d3 100644 --- a/nuttx/net/local/local_accept.c +++ b/nuttx/net/local/local_accept.c @@ -180,46 +180,12 @@ int psock_local_accept(FAR struct socket *psock, FAR struct sockaddr *addr, if (addr) { - FAR struct sockaddr_un *unaddr; - int totlen; - int pathlen; - - /* If an address is provided, then the length must also be - * provided. - */ - - DEBUGASSERT(addrlen); - - /* Get the length of the path (minus the NUL terminator) - * and the length of the whole client address. - */ - - pathlen = strnlen(client->lc_path, UNIX_PATH_MAX-1); - totlen = sizeof(sa_family_t) + pathlen + 1; - - /* If the length of the whole client address is larger - * than the buffer provided by the caller, then truncate - * the address to fit. - */ - - if (totlen > *addrlen) - { - pathlen -= (totlen - *addrlen); - totlen = *addrlen; - } - - /* Copy the Unix domain address */ - - unaddr = (FAR struct sockaddr_un *)addr; - unaddr->sun_family = AF_LOCAL; - memcpy(unaddr->sun_path, client->lc_path, pathlen); - unaddr->sun_path[pathlen] = '\0'; - - /* Return the Unix domain address size */ - - *addrlen = totlen; + ret = local_getaddr(client, addr, addrlen); } + } + if (ret == OK) + { /* Return the client connection structure */ *newconn = (FAR void *)conn; diff --git a/nuttx/net/local/local_recvfrom.c b/nuttx/net/local/local_recvfrom.c index c31bec1f2..afc44d210 100644 --- a/nuttx/net/local/local_recvfrom.c +++ b/nuttx/net/local/local_recvfrom.c @@ -43,11 +43,80 @@ #include #include #include +#include +#include #include +#include "socket/socket.h" #include "local/local.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ +/**************************************************************************** + * Name: psock_fifo_read + * + * Description: + * A thin layer aroudn local_fifo_read that handles socket-related loss-of- + * connection events. + * + ****************************************************************************/ + +static int psock_fifo_read(FAR struct socket *psock, FAR void *buf, + FAR size_t *readlen) +{ + FAR struct local_conn_s *conn = (FAR struct local_conn_s *)psock->s_conn; + int ret; + + ret = local_fifo_read(conn->lc_infd, buf, readlen); + if (ret < 0) + { + /* -ECONNRESET is a special case. We may or not have received + * data, then the peer closed the connection. + */ + + if (ret == -ECONNRESET) + { + ndbg("ERROR: Lost connection: %d\n", ret); + + /* Report an ungraceful loss of connection. This should + * eventually be reported as ENOTCONN. + */ + + psock->s_flags &= ~(_SF_CONNECTED |_SF_CLOSED); + conn->lc_state = LOCAL_STATE_DISCONNECTED; + + /* Did we receive any data? */ + + if (*readlen <= 0) + { + /* No.. return the ECONNRESET error now. Otherwise, + * process the received data and return ENOTCONN the + * next time that psock_recvfrom() is calle. + */ + + return ret; + } + } + else + { + ndbg("ERROR: Failed to read packet: %d\n", ret); + return ret; + } + } + + return OK; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -76,7 +145,7 @@ * On success, returns the number of characters sent. If no data is * available to be received and the peer has performed an orderly shutdown, * recv() will return 0. Otherwise, on errors, -1 is returned, and errno - * is set appropriately (see receivefrom for the complete list). + * is set appropriately (see receive from for the complete list). * ****************************************************************************/ @@ -84,8 +153,104 @@ ssize_t psock_local_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, int flags, FAR struct sockaddr *from, FAR socklen_t *fromlen) { -#warning Missing logic - return -ENOSYS; + FAR struct local_conn_s *conn; + size_t readlen; + int ret; + + DEBUGASSERT(psock && psock->s_conn && buf); + conn = (FAR struct local_conn_s *)psock->s_conn; + + /* Verify that this is a connected peer socket and that it has opened the + * incoming FIFO for read-only access. + */ + + if (conn->lc_type != LOCAL_STATE_CONNECTED || + conn->lc_infd < 0) + { + ndbg("ERROR: not connected\n"); + return -ENOTCONN; + } + + /* Are there still bytes in the FIFO from the last packet? */ + + if (conn->u.peer.lc_remaining == 0) + { + /* No.. Sync to the start of the next packet in the stream and get + * the size of the next packet. + */ + + ret = local_sync(conn->lc_infd); + if (ret < 0) + { + ndbg("ERROR: Failed to get packet length: %d\n", ret); + return ret; + } + else if (ret > 0xffff) + { + ndbg("ERROR: Packet is too big: %d\n", ret); + return -E2BIG; + } + + conn->u.peer.lc_remaining = (uint16_t)ret; + } + + /* Read the packet */ + /* REVISIT: Does this make sense if the socket is SOCK_DGRAM? */ + + readlen = MIN(conn->u.peer.lc_remaining, len); + ret = psock_fifo_read(psock, buf, &readlen); + if (ret < 0) + { + return ret; + } + + /* Adjust the number of bytes remaining to be read from the packet */ + + DEBUGASSERT(readlen <= conn->u.peer.lc_remaining); + conn->u.peer.lc_remaining -= readlen; + + /* If this is a SOCK_STREAM socket and there are unread bytes remaining + * in the packet, we will get those bytes the next time recv is called. + * What if this is a SOCK_DRAM? REVISIT: Here we flush the remainder of + * the packet to the bit bucket. + */ + + if (psock->s_type == SOCK_DGRAM && conn->u.peer.lc_remaining > 0) + { + uint8_t bitbucket[32]; + size_t tmplen; + + do + { + /* Read 32 bytes into the bit bucket */ + + tmplen = MIN(conn->u.peer.lc_remaining, 32); + ret = psock_fifo_read(psock, bitbucket, &tmplen); + if (ret < 0) + { + return ret; + } + + /* Adjust the number of bytes remaining to be read from the packet */ + + DEBUGASSERT(tmplen <= conn->u.peer.lc_remaining); + conn->u.peer.lc_remaining -= tmplen; + } + while (conn->u.peer.lc_remaining > 0); + } + + /* Return the address family */ + + if (from) + { + ret = local_getaddr(conn, from, fromlen); + if (ret < 0) + { + return ret; + } + } + + return readlen; } #endif /* CONFIG_NET && CONFIG_NET_LOCAL */ diff --git a/nuttx/net/local/local_recvutils.c b/nuttx/net/local/local_recvutils.c new file mode 100644 index 000000000..a7eee1c4a --- /dev/null +++ b/nuttx/net/local/local_recvutils.c @@ -0,0 +1,248 @@ +/**************************************************************************** + * net/local/local_recvpacket.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#if defined(CONFIG_NET) && defined(CONFIG_NET_LOCAL) + +#include +#include +#include +#include +#include +#include +#include + +#include "local/local.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: local_fifo_read + * + * Description: + * Read a data from the read-only FIFO. + * + * Parameters: + * fd - File descriptor of read-only FIFO. + * buf - Local to store the received data + * len - Length of data to receive [in] + * Length of data actually received [out] + * + * Return: + * Zero is returned on success; a negated errno value is returned on any + * failure. If -ECONNRESET is received, then the sending side has closed + * the FIFO. In this case, the returned data may still be valid (if the + * returned len > 0). + * + ****************************************************************************/ + +int local_fifo_read(int fd, FAR uint8_t *buf, size_t *len) +{ + ssize_t total; + ssize_t nread; + int ret; + + DEBUGASSERT(buf && len); + + total = 0; + while (len > 0) + { + nread = read(fd, buf, *len); + if (nread < 0) + { + int errcode = errno; + DEBUGASSERT(errcode > 0); + + if (errcode != EINTR) + { + ndbg("ERROR: Read failed: %d\n", errcode); + ret = -errcode; + goto errout; + } + + nvdbg("Ignoring signal\n"); + } + else if (nread == 0) + { + /* The FIFO returns zero if the sending side of the connection + * has closed the FIFO. + */ + + ret = -ECONNRESET; + goto errout; + } + else + { + DEBUGASSERT(nread <= len); + len -= nread; + buf += nread; + } + } + + ret = OK; + +errout: + *len = total; + return ret; +} + +/**************************************************************************** + * Name: local_sync + * + * Description: + * Read a sync bytes until the start of the packet is found. + * + * Parameters: + * fd - File descriptor of read-only FIFO. + * + * Return: + * The non-zero size of the following packet is returned on success; a + * negated errno value is returned on any failure. + * + ****************************************************************************/ + +int local_sync(int fd) +{ + size_t readlen; + uint16_t pktlen; + uint8_t sync; + int ret; + + /* Loop until a valid pre-amble is encountered: SYNC bytes followed + * by one END byte. + */ + + do + { + /* Read until we encounter a sync byte */ + + do + { + readlen = sizeof(uint8_t); + ret = local_fifo_read(fd, &sync, &readlen); + if (ret < 0) + { + ndbg("ERROR: Failed to read sync bytes: %d\n", ret); + return ret; + } + } + while (sync != LOCAL_SYNC_BYTE); + + /* Then read to the end of the SYNC sequence */ + + do + { + readlen = sizeof(uint8_t); + ret = local_fifo_read(fd, &sync, &readlen); + if (ret < 0) + { + ndbg("ERROR: Failed to read sync bytes: %d\n", ret); + return ret; + } + } + while (sync == LOCAL_SYNC_BYTE); + } + while (sync != LOCAL_END_BYTE); + + /* Then read the packet length */ + + readlen = sizeof(uint16_t); + ret = local_fifo_read(fd, (FAR uint8_t *)&pktlen, &readlen); + return ret < 0 ? ret : pktlen; +} + +/**************************************************************************** + * Name: local_getaddr + * + * Description: + * Return the Unix domain address of a connection. + * + * Parameters: + * conn - The connection + * addr - The location to return the address + * addrlen - The size of the memory allocated by the caller to receive the + * address. + * + * Return: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int local_getaddr(FAR struct local_conn_s *conn, FAR struct sockaddr *addr, + FAR socklen_t *addrlen) +{ + FAR struct sockaddr_un *unaddr; + int totlen; + int pathlen; + + DEBUGASSERT(conn && addr && addrlen && *addrlen >= sizeof(sa_family_t)); + + /* Get the length of the path (minus the NUL terminator) and the length + * of the whole Unix domain address. + */ + + pathlen = strnlen(conn->lc_path, UNIX_PATH_MAX-1); + totlen = sizeof(sa_family_t) + pathlen + 1; + + /* If the length of the whole Unix domain address is larger than the + * buffer provided by the caller, then truncate the address to fit. + */ + + if (totlen > *addrlen) + { + pathlen -= (totlen - *addrlen); + totlen = *addrlen; + } + + /* Copy the Unix domain address */ + + unaddr = (FAR struct sockaddr_un *)addr; + unaddr->sun_family = AF_LOCAL; + memcpy(unaddr->sun_path, conn->lc_path, pathlen); + unaddr->sun_path[pathlen] = '\0'; + + /* Return the Unix domain address size */ + + *addrlen = totlen; + return OK; +} + +#endif /* CONFIG_NET && CONFIG_NET_LOCAL */ diff --git a/nuttx/net/local/local_sendpacket.c b/nuttx/net/local/local_sendpacket.c new file mode 100644 index 000000000..3658175d6 --- /dev/null +++ b/nuttx/net/local/local_sendpacket.c @@ -0,0 +1,166 @@ +/**************************************************************************** + * net/local/local_sendpacket.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#if defined(CONFIG_NET) && defined(CONFIG_NET_LOCAL) + +#include +#include +#include +#include +#include +#include + +#include "local/local.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define LOCAL_PREAMBLE_SIZE 8 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const uint8_t g_preamble[LOCAL_PREAMBLE_SIZE] = +{ + LOCAL_SYNC_BYTE, LOCAL_SYNC_BYTE, LOCAL_SYNC_BYTE, LOCAL_SYNC_BYTE, + LOCAL_SYNC_BYTE, LOCAL_SYNC_BYTE, LOCAL_SYNC_BYTE, LOCAL_END_BYTE +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: local_fifo_write + * + * Description: + * Write a data on the write-only FIFO. + * + * Parameters: + * fd File descriptor of write-only FIFO. + * buf Data to send + * len Length of data to send + * + * Return: + * Zero is returned on success; a negated errno value is returned on any + * failure. + * + ****************************************************************************/ + +static int local_fifo_write(int fd, FAR const uint8_t *buf, size_t len) +{ + ssize_t nwritten; + + while (len > 0) + { + nwritten = write(fd, buf, len); + if (nwritten < 0) + { + int errcode = errno; + DEBUGASSERT(errcode > 0); + + if (errcode != EINTR) + { + ndbg("ERROR: Write failed: %d\n", errcode); + return -errcode; + } + + nvdbg("Ignoring signal\n"); + } + else + { + DEBUGASSERT(nwritten > 0 && nwritten <= len); + len -= nwritten; + buf += nwritten; + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: local_send_packet + * + * Description: + * Send a packet on the write-only FIFO. + * + * Parameters: + * fd File descriptor of write-only FIFO. + * buf Data to send + * len Length of data to send + * + * Return: + * Zero is returned on success; a negated errno value is returned on any + * failure. + * + ****************************************************************************/ + +int local_send_packet(int fd, FAR const uint8_t *buf, size_t len) +{ + uint16_t len16; + int ret; + + /* Send the packet preamble */ + + ret = local_fifo_write(fd, g_preamble, LOCAL_PREAMBLE_SIZE); + if (ret == OK) + { + /* Send the packet length */ + + len16 = len; + ret = local_fifo_write(fd, (FAR const uint8_t *)&len16, sizeof(uint16_t)); + if(ret == OK) + { + /* Send the packet data */ + + ret = local_fifo_write(fd, buf, len); + } + } + + return ret; +} + +#endif /* CONFIG_NET && CONFIG_NET_LOCAL */ diff --git a/nuttx/net/local/local_utils.c b/nuttx/net/local/local_utils.c deleted file mode 100644 index 5b69b650b..000000000 --- a/nuttx/net/local/local_utils.c +++ /dev/null @@ -1,205 +0,0 @@ -/**************************************************************************** - * net/local/local_utils.c - * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#if defined(CONFIG_NET) && defined(CONFIG_NET_LOCAL) - -#include -#include -#include -#include -#include -#include - -#include "local/local.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define LOCAL_PREAMBLE_SIZE 8 - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static const uint8_t g_preamble[LOCAL_PREAMBLE_SIZE] = -{ - LOCAL_SYNC_BYTE, LOCAL_SYNC_BYTE, LOCAL_SYNC_BYTE, LOCAL_SYNC_BYTE, - LOCAL_SYNC_BYTE, LOCAL_SYNC_BYTE, LOCAL_SYNC_BYTE, LOCAL_END_BYTE -}; - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: local_chksum - * - * Description: - * Compute a simple checksum over the packet data - * - * Parameters: - * buf Data to send - * len Length of data to send - * - * Return: - * The 16-bit checksum (including the length) - * - ****************************************************************************/ - -uint16_t local_chksum(FAR const uint8_t *buf, size_t len) -{ - uint16_t chksum; - int i; - - DEBUGASSERT(buf && len <= 0xffff); - - chksum = (len & 0xff) + ((len >> 8) & 0xff); - for (i = 0; i < len; i++) - { - chksum += *buf++; - } - - return chksum; -} - -/**************************************************************************** - * Name: local_write - * - * Description: - * Write a data on the write-only FIFO. - * - * Parameters: - * fd File descriptor or write-only FIFO. - * buf Data to send - * len Length of data to send - * - * Return: - * Zero is returned on success; a negated errno value is returned on any - * failure. - * - ****************************************************************************/ - -int local_write(int fd, FAR const uint8_t *buf, size_t len) -{ - ssize_t nwritten; - - while (len > 0) - { - nwritten = write(fd, buf, len); - if (nwritten < 0) - { - int errcode = errno; - DEBUGASSERT(errcode > 0); - - if (errcode != EINTR) - { - ndbg("ERROR: Write failed: %d\n", errcode); - return -errcode; - } - - nvdbg("Ignoring signal\n"); - } - else - { - DEBUGASSERT(nwritten > 0 && nwritten <= len); - len -= nwritten; - buf += nwritten; - } - } - - return OK; -} - -/**************************************************************************** - * Name: local_send_packet - * - * Description: - * Write a packet on the write-only FIFO. - * - * Parameters: - * fd File descriptor or write-only FIFO. - * buf Data to send - * len Length of data to send - * - * Return: - * Zero is returned on success; a negated errno value is returned on any - * failure. - * - ****************************************************************************/ - -int local_send_packet(int fd, FAR const uint8_t *buf, size_t len) -{ - uint16_t len16; - uint16_t chksum; - int ret; - - /* Compute the checksum over the packet data (including the length) */ - - chksum = local_chksum(buf, len); - - /* Send the packet preamble */ - - ret = local_write(fd, g_preamble, LOCAL_PREAMBLE_SIZE); - if (ret == OK) - { - /* Send the packet length */ - - len16 = len; - ret = local_write(fd, (FAR const uint8_t *)&len16, sizeof(uint16_t)); - if(ret == OK) - { - /* Send the packet data */ - - ret = local_write(fd, buf, len); - if (ret == OK) - { - /* Send the checksum */ - - ret = local_write(fd, (FAR const uint8_t *)&chksum, - sizeof(uint16_t)); - } - } - } - - return ret; -} - -#endif /* CONFIG_NET && CONFIG_NET_LOCAL */ -- cgit v1.2.3