Unix sockets: Fleshes out the recvfrom() logic
This commit is contained in:
parent
120efa4717
commit
8f29039f42
@ -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
|
||||
|
||||
|
@ -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
|
||||
*
|
||||
@ -393,6 +421,65 @@ 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);
|
||||
|
||||
/****************************************************************************
|
||||
* 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);
|
||||
|
||||
/****************************************************************************
|
||||
* 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 allocat 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);
|
||||
|
||||
/****************************************************************************
|
||||
* 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);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: local_create_fifos
|
||||
*
|
||||
@ -453,61 +540,6 @@ 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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -43,11 +43,80 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/net/net.h>
|
||||
|
||||
#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 */
|
||||
|
248
net/local/local_recvutils.c
Normal file
248
net/local/local_recvutils.c
Normal file
@ -0,0 +1,248 @@
|
||||
/****************************************************************************
|
||||
* net/local/local_recvpacket.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 <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#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 */
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* net/local/local_utils.c
|
||||
* net/local/local_sendpacket.c
|
||||
*
|
||||
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
@ -66,48 +66,17 @@ static const uint8_t g_preamble[LOCAL_PREAMBLE_SIZE] =
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
* Private 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
|
||||
* Name: local_fifo_write
|
||||
*
|
||||
* Description:
|
||||
* Write a data on the write-only FIFO.
|
||||
*
|
||||
* Parameters:
|
||||
* fd File descriptor or write-only FIFO.
|
||||
* fd File descriptor of write-only FIFO.
|
||||
* buf Data to send
|
||||
* len Length of data to send
|
||||
*
|
||||
@ -117,7 +86,7 @@ uint16_t local_chksum(FAR const uint8_t *buf, size_t len)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int local_write(int fd, FAR const uint8_t *buf, size_t len)
|
||||
static int local_fifo_write(int fd, FAR const uint8_t *buf, size_t len)
|
||||
{
|
||||
ssize_t nwritten;
|
||||
|
||||
@ -148,14 +117,18 @@ int local_write(int fd, FAR const uint8_t *buf, size_t len)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: local_send_packet
|
||||
*
|
||||
* Description:
|
||||
* Write a packet on the write-only FIFO.
|
||||
* Send a packet on the write-only FIFO.
|
||||
*
|
||||
* Parameters:
|
||||
* fd File descriptor or write-only FIFO.
|
||||
* fd File descriptor of write-only FIFO.
|
||||
* buf Data to send
|
||||
* len Length of data to send
|
||||
*
|
||||
@ -168,34 +141,22 @@ int local_write(int fd, FAR const uint8_t *buf, size_t len)
|
||||
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);
|
||||
ret = local_fifo_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));
|
||||
ret = local_fifo_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));
|
||||
}
|
||||
ret = local_fifo_write(fd, buf, len);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user