diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2015-01-27 08:05:09 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2015-01-27 08:05:09 -0600 |
commit | 071ec57b14d9e7de480e559187dd06fdb07aff77 (patch) | |
tree | 634b8f3015e957d1358634abf60d7c5e2f47153d | |
parent | 7e075f911344db3fdcf4dbcf6f83e30eed06e772 (diff) | |
download | nuttx-071ec57b14d9e7de480e559187dd06fdb07aff77.tar.gz nuttx-071ec57b14d9e7de480e559187dd06fdb07aff77.tar.bz2 nuttx-071ec57b14d9e7de480e559187dd06fdb07aff77.zip |
Local sockets: Add basic packet send logic
-rw-r--r-- | nuttx/net/local/Make.defs | 2 | ||||
-rw-r--r-- | nuttx/net/local/local.h | 73 | ||||
-rw-r--r-- | nuttx/net/local/local_send.c | 23 | ||||
-rw-r--r-- | nuttx/net/local/local_utils.c | 205 |
4 files changed, 296 insertions, 7 deletions
diff --git a/nuttx/net/local/Make.defs b/nuttx/net/local/Make.defs index 35dc643cc..cd79ede8b 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 +NET_CSRCS += local_send.c local_sendto.c local_utils.c # Include UDP build support diff --git a/nuttx/net/local/local.h b/nuttx/net/local/local.h index 275a658ac..dc733d15f 100644 --- a/nuttx/net/local/local.h +++ b/nuttx/net/local/local.h @@ -54,6 +54,18 @@ * Pre-processor Definitions ****************************************************************************/ +/* Packet format in FIFO: + * + * 1. Sync bytes (7 at most) + * 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 */ + /**************************************************************************** * Public Type Definitions ****************************************************************************/ @@ -312,7 +324,7 @@ int psock_local_accept(FAR struct socket *psock, FAR struct sockaddr *addr, * psock An instance of the internal socket structure. * buf Data to send * len Length of data to send - * flags Send flags + * flags Send flags (ignored for now) * * Return: * On success, returns the number of characters sent. On error, @@ -334,7 +346,7 @@ ssize_t psock_local_send(FAR struct socket *psock, FAR const void *buf, * psock A pointer to a NuttX-specific, internal socket structure * buf Data to send * len Length of data to send - * flags Send flags + * flags Send flags (ignored for now) * to Address of recipient * tolen The length of the address structure * @@ -365,7 +377,7 @@ ssize_t psock_local_sendto(FAR struct socket *psock, FAR const void *buf, * psock A pointer to a NuttX-specific, internal socket structure * buf Buffer to receive data * len Length of buffer - * flags Receive flags + * flags Receive flags (ignored for now) * from Address of source (may be NULL) * fromlen The length of the address structure * @@ -441,6 +453,61 @@ int local_open_server_rx(FAR struct local_conn_s *server); int local_open_server_tx(FAR struct local_conn_s *server); +/**************************************************************************** + * 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); + +/**************************************************************************** + * 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: + * On success, returns the number of characters sent. On error, a + * negated errno value is returned. + * + ****************************************************************************/ + +int local_write(int fd, FAR const uint8_t *buf, size_t len); + +/**************************************************************************** + * 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); + #undef EXTERN #ifdef __cplusplus } diff --git a/nuttx/net/local/local_send.c b/nuttx/net/local/local_send.c index b0cb1d22f..74bf7f0a4 100644 --- a/nuttx/net/local/local_send.c +++ b/nuttx/net/local/local_send.c @@ -42,6 +42,8 @@ #include <sys/types.h> #include <errno.h> +#include <assert.h> +#include <debug.h> #include <nuttx/net/net.h> @@ -61,7 +63,7 @@ * psock An instance of the internal socket structure. * buf Data to send * len Length of data to send - * flags Send flags + * flags Send flags (ignored for now) * * Return: * On success, returns the number of characters sent. On error, @@ -73,8 +75,23 @@ ssize_t psock_local_send(FAR struct socket *psock, FAR const void *buf, size_t len, int flags) { -#warning Missing logic - return -ENOSYS; + FAR struct local_conn_s *peer; + + DEBUGASSERT(psock && psock->s_conn && buf); + peer = (FAR struct local_conn_s *)psock->s_conn; + + /* Verify that this is a connected peer socket and that it has opened the + * outgoing FIFO for write-only access. + */ + + if (peer->lc_type != LOCAL_STATE_CONNECTED || + peer->lc_outfd < 0) + { + ndbg("ERROR: not connected\n"); + return -ENOTCONN; + } + + return local_send_packet(peer->lc_outfd, (FAR uint8_t *)buf, len); } #endif /* CONFIG_NET && CONFIG_NET_LOCAL */ diff --git a/nuttx/net/local/local_utils.c b/nuttx/net/local/local_utils.c new file mode 100644 index 000000000..5b69b650b --- /dev/null +++ b/nuttx/net/local/local_utils.c @@ -0,0 +1,205 @@ +/**************************************************************************** + * net/local/local_utils.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * + * 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 <nuttx/config.h> +#if defined(CONFIG_NET) && defined(CONFIG_NET_LOCAL) + +#include <sys/types.h> +#include <stdint.h> +#include <unistd.h> +#include <errno.h> +#include <assert.h> +#include <debug.h> + +#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 */ |