6loWPAN: Adding more socket send-related logic.

This commit is contained in:
Gregory Nutt 2017-03-29 14:28:51 -06:00
parent 5fb222180c
commit a6148cdb7c
7 changed files with 354 additions and 24 deletions

View File

@ -232,18 +232,91 @@
#define SIXLOWPAN_MAC_STDFRAME 127
/* Packet buffer Definitions */
#define PACKETBUF_HDR_SIZE 48
#define PACKETBUF_ATTR_PACKET_TYPE_DATA 0
#define PACKETBUF_ATTR_PACKET_TYPE_ACK 1
#define PACKETBUF_ATTR_PACKET_TYPE_STREAM 2
#define PACKETBUF_ATTR_PACKET_TYPE_STREAM_END 3
#define PACKETBUF_ATTR_PACKET_TYPE_TIMESTAMP 4
/* Packet buffer attributes (indices into i_pktattr) */
#define PACKETBUF_ATTR_NONE 0
/* Scope 0 attributes: used only on the local node. */
#define PACKETBUF_ATTR_CHANNEL 1
#define PACKETBUF_ATTR_NETWORK_ID 2
#define PACKETBUF_ATTR_LINK_QUALITY 3
#define PACKETBUF_ATTR_RSSI 4
#define PACKETBUF_ATTR_TIMESTAMP 5
#define PACKETBUF_ATTR_RADIO_TXPOWER 6
#define PACKETBUF_ATTR_LISTEN_TIME 7
#define PACKETBUF_ATTR_TRANSMIT_TIME 8
#define PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS 9
#define PACKETBUF_ATTR_MAC_SEQNO 10
#define PACKETBUF_ATTR_MAC_ACK 11
/* Scope 1 attributes: used between two neighbors only. */
#define PACKETBUF_ATTR_RELIABLE 12
#define PACKETBUF_ATTR_PACKET_ID 13
#define PACKETBUF_ATTR_PACKET_TYPE 14
#define PACKETBUF_ATTR_REXMIT 15
#define PACKETBUF_ATTR_MAX_REXMIT 16
#define PACKETBUF_ATTR_NUM_REXMIT 17
#define PACKETBUF_ATTR_PENDING 18
/* Scope 2 attributes: used between end-to-end nodes. */
#define PACKETBUF_ATTR_HOPS 11
#define PACKETBUF_ATTR_TTL 20
#define PACKETBUF_ATTR_EPACKET_ID 21
#define PACKETBUF_ATTR_EPACKET_TYPE 22
#define PACKETBUF_ATTR_ERELIABLE 23
#define PACKETBUF_NUM_ATTRS 24
/* Addresses (indices into i_pktaddr) */
#define PACKETBUF_ADDR_SENDER 0
#define PACKETBUF_ADDR_RECEIVER 1
#define PACKETBUF_ADDR_ESENDER 2
#define PACKETBUF_ADDR_ERECEIVER 3
#define PACKETBUF_NUM_ADDRS 4
/****************************************************************************
* Public Types
****************************************************************************/
/* Rime address representation */
struct rimeaddr_s
{
uint8_t u8[CONFIG_NET_6LOWPAN_RIMEADDR_SIZE];
};
/* The device structure for IEEE802.15.4 MAC network device differs from the
* standard Ethernet MAC device structure. The main reason for this
* difference is that fragmentation must be supported.
*
* The IEEE802.15.4 MAC does not use the d_buf packet buffer directly.
* Rather, it uses a smaller frame buffer. The packet data is provided to
* the frame buffer each time that the IEEE802.15.4 MAC needs to send
* more data.
* Rather, it uses a smaller frame buffer, i_frame.
*
* - The packet fragment data is provided to the i_frame buffer each time
* that the IEEE802.15.4 MAC needs to send more data. The length of
* the frame is provided in i_frame.
*
* In this case, the d_buf holds the packet data yet to be sent; d_len
* holds the size of entire packet.
*
* - Received frames are provided by IEEE802.15.4 MAC to the network
* via i_frame with length i_framelen for reassembly in d_buf; d_len
* will hold the size of the reassembled packet.
*
* This is accomplished by "inheriting" the standard 'struct net_driver_s'
* and appending the frame buffer as well as other metadata needed to
@ -286,6 +359,40 @@ struct ieee802154_driver_s
*/
uint16_t i_framelen;
/* The following fields are device-specific metadata used by the 6loWPAN
* stack and should not be modified by the IEEE802.15.4 MAC network drvier.
*/
/* A pointer to the rime buffer.
*
* We initialize it to the beginning of the rime buffer, then access
* different fields by updating the offset ieee->i_rime_hdrlen.
*/
FAR uint8_t *i_rimeptr;
/* i_uncomp_hdrlen is the length of the headers before compression (if HC2
* is used this includes the UDP header in addition to the IP header).
*/
uint8_t i_uncomp_hdrlen;
/* i_rime_hdrlen is the total length of (the processed) 6lowpan headers
* (fragment headers, IPV6 or HC1, HC2, and HC1 and HC2 non compressed
* fields).
*/
uint8_t i_rime_hdrlen;
/* Next available pointer into header */
uint8_t i_hdrptr;
/* Packet buffer metadata: Attributes and addresses */
uint16_t i_pktattrs[PACKETBUF_NUM_ATTRS];
struct rimeaddr_s i_pktaddrs[PACKETBUF_NUM_ADDRS];
};
/* The structure of a next header compressor. This compressor is provided
@ -357,6 +464,8 @@ void sixlowpan_set_compressor(FAR struct sixlowpan_nhcompressor_s *compressor);
*
****************************************************************************/
#ifdef CONFIG_NET_6LOWPAN_SNIFFER
void sixlowpan_set_sniffer(FAR struct sixlowpan_rime_sniffer_s *sniffer);
#endif
#endif /* __INCLUDE_NUTTX_NET_SIXLOWOAN_H */

View File

@ -169,4 +169,10 @@ config NET_6LOWPAN_TCP_RECVWNDO
is slow to process incoming data, or high (32768 bytes) if the
application processes data quickly. REVISIT!
config NET_6LOWPAN_SNIFFER
default n
---help---
Enable use use an architecture-specific sniffer to support tracing
of IP.
endif # NET_6LOWPAN

View File

@ -39,9 +39,9 @@ ifeq ($(CONFIG_NET_6LOWPAN),y)
# Include IEEE 802.15.4 file in the build
NET_CSRCS += sixlowpan_initialize.c sixlowpan_globals.c
NET_CSRCS += sixlowpan_initialize.c sixlowpan_globals.c sixlowpan_utils.c
NET_CSRCS += sixlowpan_input.c sixlowpan_send.c
NET_CSRCS += sixlowpan_compressor.c sixlowpan_sniffer.c
NET_CSRCS += sixlowpan_compressor.c
ifeq ($(CONFIG_NET_6LOWPAN_COMPRESSION_HC1),y)
NET_CSRCS += sixlowpan_hc1.c
@ -51,6 +51,10 @@ ifeq ($(CONFIG_NET_6LOWPAN_COMPRESSION_HC06),y)
NET_CSRCS += sixlowpan_hc06.c
endif
ifeq ($(CONFIG_NET_6LOWPAN_SNIFFER),y)
NET_CSRCS += sixlowpan_sniffer.c
endif
# Include the sixlowpan directory in the build
DEPPATH += --dep-path sixlowpan

View File

@ -61,13 +61,6 @@
* Public Types
****************************************************************************/
/* Rime address representation */
struct rimeaddr_s
{
uint8_t u8[CONFIG_NET_6LOWPAN_RIMEADDR_SIZE];
};
/****************************************************************************
* Public Data
****************************************************************************/
@ -77,10 +70,16 @@ struct rimeaddr_s
struct sixlowpan_nhcompressor_s; /* Foward reference */
extern FAR struct sixlowpan_nhcompressor_s *g_sixlowpan_compressor;
#ifdef CONFIG_NET_6LOWPAN_SNIFFER
/* Rime Sniffer support for one single listener to enable trace of IP */
struct sixlowpan_rime_sniffer_s; /* Foward reference */
extern FAR struct sixlowpan_rime_sniffer_s *g_sixlowpan_sniffer;
#endif
/* All zero rime address */
extern const struct rimeaddr_s g_rimeaddr_null;
/****************************************************************************
* Public Types
@ -90,8 +89,10 @@ extern FAR struct sixlowpan_rime_sniffer_s *g_sixlowpan_sniffer;
* Public Function Prototypes
****************************************************************************/
struct net_driver_s; /* Forward reference */
struct socket; /* Forward reference */
struct net_driver_s; /* Forward reference */
struct ieee802154_driver_s; /* Forward reference */
struct rimeaddr_s; /* Forward reference */
struct socket; /* Forward reference */
/****************************************************************************
* Name: sixlowpan_initialize
@ -132,6 +133,9 @@ void sixlowpan_initialize(void);
* must be consistent with definition of errors reported by send() or
* sendto().
*
* Assumptions:
* Called with the network locked.
*
****************************************************************************/
#ifdef CONFIG_NET_TCP
@ -157,6 +161,9 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
* must be consistent with definition of errors reported by send() or
* sendto().
*
* Assumptions:
* Called with the network locked.
*
****************************************************************************/
#ifdef CONFIG_NET_UDP
@ -319,5 +326,16 @@ void sixlowpan_uncompresshdr_hc1(FAR struct net_driver_s *dev,
uint16_t ip_len);
#endif
/****************************************************************************
* Name: sixlowpan_pktbuf_reset
*
* Description:
* Reset all attributes and addresses in the packet buffer metadata in the
* provided IEEE802.15.4 MAC driver structure.
*
****************************************************************************/
void sixlowpan_pktbuf_reset(FAR struct ieee802154_driver_s *ieee);
#endif /* CONFIG_NET_6LOWPAN */
#endif /* _NET_SIXLOWPAN_SIXLOWPAN_H */

View File

@ -53,8 +53,10 @@
FAR struct sixlowpan_nhcompressor_s *g_sixlowpan_compressor;
#ifdef CONFIG_NET_6LOWPAN_SNIFFER
/* A pointer to the optional, architecture-specific sniffer */
FAR struct sixlowpan_rime_sniffer_s *g_sixlowpan_sniffer;
#endif
#endif /* CONFIG_NET_6LOWPAN */

View File

@ -39,12 +39,17 @@
#include <nuttx/config.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include "nuttx/net/net.h"
#include "nuttx/net/netdev.h"
#include "nuttx/net/ip.h"
#include "nuttx/net/tcp.h"
#include "nuttx/net/udp.h"
#include "nuttx/net/icmpv6.h"
#include "nuttx/net/sixlowpan.h"
#include "netdev/netdev.h"
#include "socket/socket.h"
@ -54,11 +59,133 @@
#ifdef CONFIG_NET_6LOWPAN
/****************************************************************************
* Private Types
****************************************************************************/
/* IPv6 + TCP header */
struct ipv6tcp_hdr_s
{
struct ipv6_hdr_s ipv6;
struct tcp_hdr_s tcp;
};
/* IPv6 + UDP header */
struct ipv6udp_hdr_s
{
struct ipv6_hdr_s ipv6;
struct udp_hdr_s udp;
};
/* IPv6 + ICMPv6 header */
struct ipv6icmp_hdr_s
{
struct ipv6_hdr_s ipv6;
struct icmpv6_iphdr_s icmp;
};
/****************************************************************************
* Public Functions
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: sixlowpan_set_pktattrs
*
* Description:
* Setup some packet buffer attributes
* Input Parameters:
* ieee - Pointer to IEEE802.15.4 MAC driver structure.
* ipv6 - Pointer to the IPv6 header to "compress"
*
* Returned Value:
* None
*
****************************************************************************/
static void sixlowpan_set_pktattrs(FAR struct ieee802154_driver_s *ieee,
FAR const struct ipv6_hdr_s *ipv6)
{
int attr = 0;
/* Set protocol in NETWORK_ID */
ieee->i_pktattrs[PACKETBUF_ATTR_NETWORK_ID] = ipv6->proto;
/* Assign values to the channel attribute (port or type + code) */
if (ipv6->proto == IP_PROTO_UDP)
{
FAR struct udp_hdr_s *udp = &((FAR struct ipv6udp_hdr_s *)ipv6)->udp;
attr = udp->srcport;
if (udp->destport < attr)
{
attr = udp->destport;
}
}
else if (ipv6->proto == IP_PROTO_TCP)
{
FAR struct tcp_hdr_s *tcp = &((FAR struct ipv6tcp_hdr_s *)ipv6)->tcp;
attr = tcp->srcport;
if (tcp->destport < attr)
{
attr = tcp->destport;
}
}
else if (ipv6->proto == IP_PROTO_ICMP6)
{
FAR struct icmpv6_iphdr_s *icmp = &((FAR struct ipv6icmp_hdr_s *)ipv6)->icmp;
attr = icmp->type << 8 | icmp->code;
}
ieee->i_pktattrs[PACKETBUF_ATTR_CHANNEL] = attr;
}
/****************************************************************************
* Name: sixlowpan_compress_ipv6hdr
*
* Description:
* IPv6 dispatch "compression" function. Packets "Compression" when only
* IPv6 dispatch is used
*
* There is no compression in this case, all fields are sent
* inline. We just add the IPv6 dispatch byte before the packet.
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | IPv6 Dsp | IPv6 header and payload ...
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* Input Parameters:
* ieee - Pointer to IEEE802.15.4 MAC driver structure.
* ipv6 - Pointer to the IPv6 header to "compress"
*
* Returned Value:
* None
*
****************************************************************************/
static void sixlowpan_compress_ipv6hdr(FAR struct ieee802154_driver_s *ieee,
FAR const struct ipv6_hdr_s *ipv6)
{
/* Indicate the IPv6 dispatch and length */
*ieee->i_rimeptr = SIXLOWPAN_DISPATCH_IPV6;
ieee->i_rime_hdrlen += SIXLOWPAN_IPV6_HDR_LEN;
/* Copy the IPv6 header and adjust pointers */
memcpy(ieee->i_rimeptr + ieee->i_rime_hdrlen, ipv6, IPv6_HDRLEN);
ieee->i_rime_hdrlen += IPv6_HDRLEN;
ieee->i_uncomp_hdrlen += IPv6_HDRLEN;
}
/****************************************************************************
* Name: sixlowpan_send
*
@ -76,6 +203,7 @@
*
* Input Parameters:
* dev - The IEEE802.15.4 MAC network driver interface.
* ipv6 - IPv6 plus TCP or UDP headers.
* raddr - The MAC address of the destination
*
* Returned Value:
@ -89,13 +217,60 @@
*
****************************************************************************/
int sixlowpan_send(FAR struct net_driver_s *dev, net_ipv6addr_t raddr)
int sixlowpan_send(FAR struct net_driver_s *dev,
FAR const struct ipv6_hdr_s *ipv6, net_ipv6addr_t raddr)
{
FAR struct ieee802154_driver_s *ieee = (FAR struct ieee802154_driver_s *)dev;
net_lock();
/* REVISIT: To be provided */
net_unlock();
int framer_hdrlen; /* Framer header length */
struct rimeaddr_s dest; /* The MAC address of the destination of the packet */
uint16_t outlen; /* Number of bytes processed. */
/* Initialize device-specific data */
ieee->i_uncomp_hdrlen = 0;
ieee->i_rime_hdrlen = 0;
/* Reset rime buffer, packet buffer metatadata */
dev->d_len = 0;
sixlowpan_pktbuf_reset(ieee);
ieee->i_rimeptr = &dev->d_buf[PACKETBUF_HDR_SIZE];
ieee->i_pktattrs[PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS] = CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS;
#ifdef CONFIG_NET_6LOWPAN_SNIFFER
if (g_sixlowpan_sniffer != NULL)
{
/* Call the attribution when the callback comes, but set attributes here */
sixlowpan_set_pktattrs(ieee, ipv6);
}
#endif
/* Set stream mode for all TCP packets, except FIN packets. */
if (ipv6->proto == IP_PROTO_TCP)
{
FAR const struct tcp_hdr_s *tcp = &((FAR const struct ipv6tcp_hdr_s *)ipv6)->tcp;
if ((tcp->flags & TCP_FIN) == 0 &&
(tcp->flags & TCP_CTL) != TCP_ACK)
{
ieee->i_pktattrs[PACKETBUF_ATTR_PACKET_TYPE] = PACKETBUF_ATTR_PACKET_TYPE_STREAM;
}
else if ((tcp->flags & TCP_FIN) == TCP_FIN)
{
ieee->i_pktattrs[PACKETBUF_ATTR_PACKET_TYPE] = PACKETBUF_ATTR_PACKET_TYPE_STREAM_END;
}
}
/* The destination address will be tagged to each outbound packet. If the
* argument raddr is NULL, we are sending a broadcast packet.
*/
#warning Missing logic
return -ENOSYS;
}
@ -121,6 +296,9 @@ int sixlowpan_send(FAR struct net_driver_s *dev, net_ipv6addr_t raddr)
* must be consistent with definition of errors reported by send() or
* sendto().
*
* Assumptions:
* Called with the network locked.
*
****************************************************************************/
#ifdef CONFIG_NET_TCP
@ -129,6 +307,7 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
{
FAR struct tcp_conn_s *conn;
FAR struct net_driver_s *dev;
struct ipv6tcp_hdr_s ipv6tcp;
int ret;
DEBUGASSERT(psock != NULL && psock->s_crefs > 0);
@ -194,6 +373,9 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
}
#endif
/* Initialize the IPv6/TCP headers */
#warning Missing logic
/* Set the socket state to sending */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
@ -202,7 +384,8 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
* packet.
*/
ret = sixlowpan_send(dev, conn->u.ipv6.raddr);
ret = sixlowpan_send(dev, (FAR const struct ipv6_hdr_s *)&ipv6tcp,
conn->u.ipv6.raddr);
if (ret < 0)
{
nerr("ERROR: sixlowpan_send() failed: %d\n", ret);
@ -230,6 +413,9 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
* must be consistent with definition of errors reported by send() or
* sendto().
*
* Assumptions:
* Called with the network locked.
*
****************************************************************************/
#ifdef CONFIG_NET_UDP
@ -238,6 +424,7 @@ ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf,
{
FAR struct udp_conn_s *conn;
FAR struct net_driver_s *dev;
struct ipv6udp_hdr_s ipv6udp;
int ret;
DEBUGASSERT(psock != NULL && psock->s_crefs > 0);
@ -304,6 +491,9 @@ ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf,
}
#endif
/* Initialize the IPv6/UDP headers */
#warning Missing logic
/* Set the socket state to sending */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
@ -312,7 +502,8 @@ ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf,
* packet.
*/
ret = sixlowpan_send(dev, conn->u.ipv6.raddr);
ret = sixlowpan_send(dev, (FAR const struct ipv6_hdr_s *)&ipv6udp,
conn->u.ipv6.raddr);
if (ret < 0)
{
nerr("ERROR: sixlowpan_send() failed: %d\n", ret);

View File

@ -44,7 +44,7 @@
#include "sixlowpan/sixlowpan.h"
#ifdef CONFIG_NET_6LOWPAN
#ifdef CONFIG_NET_6LOWPAN_SNIFFER
/****************************************************************************
* Public Functions
@ -78,4 +78,4 @@ void sixlowpan_set_sniffer(FAR struct sixlowpan_rime_sniffer_s *sniffer)
net_unlock();
}
#endif /* CONFIG_NET_6LOWPAN */
#endif /* CONFIG_NET_6LOWPAN_SNIFFER */