Merge remote-tracking branch 'origin/master' into ieee802154

This commit is contained in:
Gregory Nutt
2017-04-02 14:39:45 -06:00
22 changed files with 2556 additions and 597 deletions
+1 -3
View File
@@ -90,9 +90,7 @@
# error "Logic to support multiple Ethernet interfaces is incomplete"
#endif
/* If processing is not done at the interrupt level, then work queue support
* is required.
*/
/* Work queue support is required. */
#if !defined(CONFIG_SCHED_WORKQUEUE)
# error Work queue support is required
+81 -2
View File
@@ -483,7 +483,7 @@ EXTERN const net_ipv6addr_t g_ipv6_llnetmask; /* Netmask for local link addres
#endif
/****************************************************************************
* Function: net_ipv4addr_maskcmp and net_ipv6addr_maskcmp
* Name: net_ipv4addr_maskcmp and net_ipv6addr_maskcmp
*
* Description:
* Compare two IP addresses under a netmask. The mask is used to mask
@@ -527,7 +527,86 @@ bool net_ipv6addr_maskcmp(const net_ipv6addr_t addr1,
#endif
/****************************************************************************
* Function: net_ipaddr_mask
* Name: net_ipv6addr_prefixcmp
*
* Description:
* Compare two IPv6 address prefixes.
*
****************************************************************************/
#define net_ipv6addr_prefixcmp(addr1, addr2, length) \
(memcmp(addr1, addr2, length >> 3) == 0)
/****************************************************************************
* Name: net_is_addr_loopback
*
* Description:
* Is Ithe Pv6 address a the loopback address?
*
****************************************************************************/
#define net_is_addr_loopback(a) \
((a)[0] == 0 && (a)[1] == 0 && (a)[2] == 0 && (a)[3] == 0 && \
(a)[4] == 0 && (a)[5] == 0 && (a)[6] == 0 && (a)[7] == 0x0001)
/****************************************************************************
* Name: net_is_addr_unspecified
*
* Description:
* Is Ithe Pv6 address the unspecified address?
*
****************************************************************************/
#define net_is_addr_unspecified(a) \
((a)[0] == 0 && (a)[1] == 0 && (a)[2] == 0 && (a)[3] == 0 && \
(a)[4] == 0 && (a)[5] == 0 && (a)[6] == 0 && (a)[7] == 0)
/****************************************************************************
* Name: net_is_addr_mcast
*
* Description:
* s address a multicast address? see RFC 3513.
*
****************************************************************************/
#define net_is_addr_mcast(a) (((a)[0] & 0xff00) == 0xff00)
/****************************************************************************
* Name: net_is_addr_linklocal_allnodes_mcast
*
* Description:
* Is IPv6 address a the link local all-nodes multicast address?
*
****************************************************************************/
#define net_is_addr_linklocal_allnodes_mcast(a) \
((a)[0] == 0xff02 && (a)[1] == 0 && (a)[2] == 0 && (a)[3] == 0 && \
(a)[4] == 0 && (a)[5] == 0 && (a)[6] == 0 && (a)[7] == 0x0001)
/****************************************************************************
* Name: net_is_addr_linklocal_allrouters_mcast
*
* Description:
* Is IPv6 address a the link local all-routers multicast address?
*
****************************************************************************/
#define net_is_addr_linklocal_allrouters_mcast(a) \
((a)[0] == 0xff02 && (a)[1] == 0 && (a)[2] == 0 && (a)[3] == 0 && \
(a)[4] == 0 && (a)[5] == 0 && (a)[6] == 0 && (a)[7] == 0x0002)
/****************************************************************************
* Name: net_is_addr_linklocal
*
* Description:
* Checks whether the address a is link local.
*
****************************************************************************/
#define net_is_addr_linklocal(a) ((a)[0] == 0xfe80)
/****************************************************************************
* Name: net_ipaddr_mask
*
* Description:
* Mask out the network part of an IP address, given the address and
+68 -99
View File
@@ -336,67 +336,51 @@
#endif
#ifdef CONFIG_NET_MULTILINK
# undef __LAST_MIN_UDP_MSS
# undef __LAST_MAX_UDP_MSS
# ifdef CONFIG_NET_ETHERNET
# ifdef __LAST_MIN_UDP_MSS
# define __MIN_UDP_MSS(h) MIN(ETH_UDP_MSS(h),__LAST_MIN_UDP_MSS(h))
# define __MAX_UDP_MSS(h) MAX(ETH_UDP_MSS(h),__LAST_MAX_UDP_MSS(h))
# else
# define __MIN_UDP_MSS(h) ETH_UDP_MSS(h)
# define __MAX_UDP_MSS(h) ETH_UDP_MSS(h)
# endif
# undef __LAST_MIN_UDP_MSS
# undef __LAST_MAX_UDP_MSS
# define __LAST_MIN_UDP_MSS(h) __MIN_UDP_MSS(h)
# define __LAST_MAX_UDP_MSS(h) __MAX_UDP_MSS(h)
# define __MIN_UDP_MSS(h) ETH_UDP_MSS(h)
# define __MAX_UDP_MSS(h) ETH_UDP_MSS(h)
# define __ETH_MIN_UDP_MSS(h) ETH_UDP_MSS(h)
# define __ETH_MAX_UDP_MSS(h) ETH_UDP_MSS(h)
# else
# define __ETH_MIN_UDP_MSS(h) INT_MAX
# define __ETH_MAX_UDP_MSS(h) 0
# endif
# ifdef CONFIG_NET_6LOWPAN
# ifdef __LAST_MIN_UDP_MSS
# define __MIN_UDP_MSS(h) MIN(IEEE802154_UDP_MSS(h),__LAST_MIN_UDP_MSS(h))
# define __MAX_UDP_MSS(h) MAX(IEEE802154_UDP_MSS(h),__LAST_MAX_UDP_MSS(h))
# else
# define __MIN_UDP_MSS(h) IEEE802154_UDP_MSS(h)
# define __MAX_UDP_MSS(h) IEEE802154_UDP_MSS(h)
# endif
# undef __LAST_MIN_UDP_MSS
# undef __LAST_MAX_UDP_MSS
# define __LAST_MIN_UDP_MSS(h) __MIN_UDP_MSS(h)
# define __LAST_MAX_UDP_MSS(h) __MAX_UDP_MSS(h)
# undef __MIN_UDP_MSS
# undef __MIN_UDP_MSS
# define __MIN_UDP_MSS(h) MIN(IEEE802154_UDP_MSS(h),__ETH_MIN_UDP_MSS(h))
# define __MAX_UDP_MSS(h) MAX(IEEE802154_UDP_MSS(h),__ETH_MAX_UDP_MSS(h))
# define __6LOWPAN_MIN_UDP_MSS(h) MIN(IEEE802154_UDP_MSS(h),__ETH_MIN_UDP_MSS(h))
# define __6LOWPAN_MAX_UDP_MSS(h) MAX(IEEE802154_UDP_MSS(h),__ETH_MAX_UDP_MSS(h))
# else
# define __6LOWPAN_MIN_UDP_MSS(h) __ETH_MIN_UDP_MSS(h)
# define __6LOWPAN_MAX_UDP_MSS(h) __ETH_MAX_UDP_MSS(h)
# endif
# ifdef CONFIG_NET_LOOPBACK
# ifdef __LAST_MIN_UDP_MSS
# define __MIN_UDP_MSS(h) MIN(LO_UDP_MSS(h),__LAST_MIN_UDP_MSS(h))
# define __MAX_UDP_MSS(h) MAX(LO_UDP_MSS(h),__LAST_MAX_UDP_MSS(h))
# else
# define __MIN_UDP_MSS(h) LO_UDP_MSS(h)
# define __MAX_UDP_MSS(h) LO_UDP_MSS(h)
# endif
# undef __LAST_MIN_UDP_MSS
# undef __LAST_MAX_UDP_MSS
# define __LAST_MIN_UDP_MSS(h) __MIN_UDP_MSS(h)
# define __LAST_MAX_UDP_MSS(h) __MAX_UDP_MSS(h)
# undef __MIN_UDP_MSS
# undef __MIN_UDP_MSS
# define __MIN_UDP_MSS(h) MIN(LO_UDP_MSS(h),__6LOWPAN_MIN_UDP_MSS(h))
# define __MAX_UDP_MSS(h) MAX(LO_UDP_MSS(h),__6LOWPAN_MAX_UDP_MSS(h))
# define __LOOP_MIN_UDP_MSS(h) MIN(LO_UDP_MSS(h),__6LOWPAN_MIN_UDP_MSS(h))
# define __LOOP_MAX_UDP_MSS(h) MAX(LO_UDP_MSS(h),__6LOWPAN_MAX_UDP_MSS(h))
# else
# define __LOOP_MIN_UDP_MSS(h) __6LOWPAN_MIN_UDP_MSS(h)
# define __LOOP_MAX_UDP_MSS(h) __6LOWPAN_MAX_UDP_MSS(h)
# endif
# ifdef CONFIG_NET_SLIP
# ifdef __LAST_MIN_UDP_MSS
# define __MIN_UDP_MSS(h) MIN(SLIP_UDP_MSS(h),__LAST_MIN_UDP_MSS(h))
# define __MAX_UDP_MSS(h) MAX(SLIP_UDP_MSS(h),__LAST_MAX_UDP_MSS(h))
# else
# define __MIN_UDP_MSS(h) SLIP_UDP_MSS(h)
# define __MAX_UDP_MSS(h) SLIP_UDP_MSS(h)
# endif
# undef __LAST_MIN_UDP_MSS
# undef __LAST_MAX_UDP_MSS
# define __LAST_MIN_UDP_MSS(h) __MIN_UDP_MSS(h)
# define __LAST_MAX_UDP_MSS(h) __MAX_UDP_MSS(h)
# undef __MIN_UDP_MSS
# undef __MIN_UDP_MSS
# define __MIN_UDP_MSS(h) MIN(SLIP_UDP_MSS(h),__LOOP_MIN_UDP_MSS(h))
# define __MAX_UDP_MSS(h) MAX(SLIP_UDP_MSS(h),__LOOP_MAX_UDP_MSS(h))
# define __SLIP_MIN_UDP_MSS(h) MIN(SLIP_UDP_MSS(h),__LOOP_MIN_UDP_MSS(h))
# define __SLIP_MAX_UDP_MSS(h) MAX(SLIP_UDP_MSS(h),__LOOP_MAX_UDP_MSS(h))
# else
# define __SLIP_MIN_UDP_MSS(h) __LOOP_MIN_UDP_MSS(h)
# define __SLIP_MAX_UDP_MSS(h) __LOOP_MAX_UDP_MSS(h)
# endif
# undef __LAST_MIN_UDP_MSS
# undef __LAST_MAX_UDP_MSS
#endif
/* NOTE: MSS calcuation excludes the UDP_HDRLEN. */
@@ -531,67 +515,52 @@
#endif
#ifdef CONFIG_NET_MULTILINK
# undef __LAST_MIN_TCP_MSS
# undef __LAST_MAX_TCP_MSS
# ifdef CONFIG_NET_ETHERNET
# ifdef __LAST_MIN_TCP_MSS
# define __MIN_TCP_MSS(h) MIN(ETH_TCP_MSS(h),__LAST_MIN_TCP_MSS(h))
# define __MAX_TCP_MSS(h) MAX(ETH_TCP_MSS(h),__LAST_MAX_TCP_MSS(h))
# else
# define __MIN_TCP_MSS(h) ETH_TCP_MSS(h)
# define __MAX_TCP_MSS(h) ETH_TCP_MSS(h)
# endif
# undef __LAST_MIN_TCP_MSS
# undef __LAST_MAX_TCP_MSS
# define __LAST_MIN_TCP_MSS(h) __MIN_TCP_MSS(h)
# define __LAST_MAX_TCP_MSS(h) __MAX_TCP_MSS(h)
# define __MIN_TCP_MSS(h) ETH_TCP_MSS(h)
# define __MAX_TCP_MSS(h) ETH_TCP_MSS(h)
# define __ETH_MIN_TCP_MSS(h) ETH_TCP_MSS(h)
# define __ETH_MAX_TCP_MSS(h) ETH_TCP_MSS(h)
# else
# define __ETH_MIN_TCP_MSS(h) INT_MAX
# define __ETH_MAX_TCP_MSS(h) 0
# endif
# ifdef CONFIG_NET_6LOWPAN
# ifdef __LAST_MIN_TCP_MSS
# define __MIN_TCP_MSS(h) MIN(IEEE802154_TCP_MSS(h),__LAST_MIN_TCP_MSS(h))
# define __MAX_TCP_MSS(h) MAX(IEEE802154_TCP_MSS(h),__LAST_MAX_TCP_MSS(h))
# else
# define __MIN_TCP_MSS(h) IEEE802154_TCP_MSS(h)
# define __MAX_TCP_MSS(h) IEEE802154_TCP_MSS(h)
# endif
# undef __LAST_MIN_TCP_MSS
# undef __LAST_MAX_TCP_MSS
# define __LAST_MIN_TCP_MSS(h) __MIN_TCP_MSS(h)
# define __LAST_MAX_TCP_MSS(h) __MAX_TCP_MSS(h)
# undef __MIN_TCP_MSS
# undef __MAX_TCP_MSS
# define __MIN_TCP_MSS(h) MIN(IEEE802154_TCP_MSS(h),__ETH_MIN_TCP_MSS(h))
# define __MAX_TCP_MSS(h) MAX(IEEE802154_TCP_MSS(h),__ETH_MAX_TCP_MSS(h))
# define __6LOWPAN_MIN_TCP_MSS(h) MIN(IEEE802154_TCP_MSS(h),__ETH_MIN_TCP_MSS(h))
# define __6LOWPAN_MAX_TCP_MSS(h) MAX(IEEE802154_TCP_MSS(h),__ETH_MAX_TCP_MSS(h))
# else
# define __6LOWPAN_MIN_TCP_MSS(h) __ETH_MIN_TCP_MSS(h)
# define __6LOWPAN_MAX_TCP_MSS(h) __ETH_MAX_TCP_MSS(h)
# endif
# ifdef CONFIG_NET_LOOPBACK
# ifdef __LAST_MIN_TCP_MSS
# define __MIN_TCP_MSS(h) MIN(LO_TCP_MSS(h),__LAST_MIN_TCP_MSS(h))
# define __MAX_TCP_MSS(h) MAX(LO_TCP_MSS(h),__LAST_MAX_TCP_MSS(h))
# else
# define __MIN_TCP_MSS(h) LO_TCP_MSS(h)
# define __MAX_TCP_MSS(h) LO_TCP_MSS(h)
# endif
# undef __LAST_MIN_TCP_MSS
# undef __LAST_MAX_TCP_MSS
# define __LAST_MIN_TCP_MSS(h) __MIN_TCP_MSS(h)
# define __LAST_MAX_TCP_MSS(h) __MAX_TCP_MSS(h)
# undef __MIN_TCP_MSS
# undef __MAX_TCP_MSS
# define __MIN_TCP_MSS(h) MIN(LO_TCP_MSS(h),__6LOWPAN_MIN_TCP_MSS(h))
# define __MAX_TCP_MSS(h) MAX(LO_TCP_MSS(h),__6LOWPAN_MAX_TCP_MSS(h))
# define __LOOP_MIN_TCP_MSS(h) MIN(LO_TCP_MSS(h),__6LOWPAN_MIN_TCP_MSS(h))
# define __LOOP_MAX_TCP_MSS(h) MAX(LO_TCP_MSS(h),__6LOWPAN_MAX_TCP_MSS(h))
# else
# define __LOOP_MIN_TCP_MSS(h) _6LOWPAN_MIN_TCP_MSS(h)
# define __LOOP_MAX_TCP_MSS(h) __6LOWPAN_MAX_TCP_MSS(h)
# endif
# ifdef CONFIG_NET_SLIP
# ifdef __LAST_MIN_TCP_MSS
# define __MIN_TCP_MSS(h) MIN(SLIP_TCP_MSS(h),__LAST_MIN_TCP_MSS(h))
# define __MAX_TCP_MSS(h) MAX(SLIP_TCP_MSS(h),__LAST_MAX_TCP_MSS(h))
# else
# define __MIN_TCP_MSS(h) SLIP_TCP_MSS(h)
# define __MAX_TCP_MSS(h) SLIP_TCP_MSS(h)
# endif
# undef __LAST_MIN_TCP_MSS
# undef __LAST_MAX_TCP_MSS
# define __LAST_MIN_TCP_MSS(h) __MIN_TCP_MSS(h)
# define __LAST_MAX_TCP_MSS(h) __MAX_TCP_MSS(h)
# undef __MIN_TCP_MSS
# undef __MAX_TCP_MSS
# define __MIN_TCP_MSS(h) MIN(SLIP_TCP_MSS(h),__LOOP_MIN_TCP_MSS(h))
# define __MAX_TCP_MSS(h) MAX(SLIP_TCP_MSS(h),__LOOP_MAX_TCP_MSS(h))
# define __SLIP_MIN_TCP_MSS(h) MIN(SLIP_TCP_MSS(h),__LOOP_MIN_TCP_MSS(h))
# define __SLIP_MAX_TCP_MSS(h) MAX(SLIP_TCP_MSS(h),__LOOP_MAX_TCP_MSS(h))
# else
# define __SLIP_MIN_TCP_MSS(h) __LOOP_MIN_TCP_MSS(h)
# define __SLIP_MAX_TCP_MSS(h) __LOOP_MAX_TCP_MSS(h)
# endif
# undef __LAST_MIN_TCP_MSS
# undef __LAST_MAX_TCP_MSS
#endif
/* If IPv4 is supported, it will have the larger MSS.
+38 -108
View File
@@ -53,6 +53,7 @@
#include <stdint.h>
#include <nuttx/clock.h>
#include <nuttx/net/iob.h>
#include <nuttx/net/netdev.h>
@@ -71,9 +72,13 @@
#define SIXLOWPAN_DISPATCH_IPV6 0x41 /* 01000001 = 65 */
#define SIXLOWPAN_DISPATCH_HC1 0x42 /* 01000010 = 66 */
#define SIXLOWPAN_DISPATCH_IPHC 0x60 /* 011xxxxx = ... */
#define SIXLOWPAN_DISPATCH_IPHC 0x60 /* 011xxxxx */
#define SIXLOWPAN_DISPATCH_IPHC_MASK 0xe0 /* 11100000 */
#define SIXLOWPAN_DISPATCH_FRAG1 0xc0 /* 11000xxx */
#define SIXLOWPAN_DISPATCH_FRAGN 0xe0 /* 11100xxx */
#define SIXLOWPAN_DISPATCH_FRAG_MASK 0xf1 /* 11111000 */
/* HC1 encoding */
@@ -155,77 +160,6 @@
#define SIXLOWPAN_FRAG1_HDR_LEN 4
#define SIXLOWPAN_FRAGN_HDR_LEN 5
/* Address compressibility test macros */
/* Check whether we can compress the IID in address 'a' to 16 bits. This is
* used for unicast addresses only, and is true if the address is on the
* format <PREFIX>::0000:00ff:fe00:XXXX
*
* NOTE: we currently assume 64-bits prefixes
*/
#define SIXLOWPAN_IS_IID_16BIT_COMPRESSABLE(a) \
((((a)->u16[4]) == 0) && \
// (((a)->u8[10]) == 0)&& \
(((a)->u8[11]) == 0xff)&& \
(((a)->u8[12]) == 0xfe)&& \
(((a)->u8[13]) == 0))
/* Check whether the 9-bit group-id of the compressed multicast address is
* known. It is true if the 9-bit group is the all nodes or all routers
* group. Parameter 'a' is typed uint8_t *
*/
#define SIXLOWPAN_IS_MCASTADDR_DECOMPRESSABLE(a) \
(((*a & 0x01) == 0) && \
((*(a + 1) == 0x01) || (*(a + 1) == 0x02)))
/* Check whether the 112-bit group-id of the multicast address is mappable
* to a 9-bit group-id. It is true if the group is the all nodes or all
* routers group.
*/
#define SIXLOWPAN_IS_MCASTADDR_COMPRESSABLE(a) \
((((a)->u16[1]) == 0) && \
(((a)->u16[2]) == 0) && \
(((a)->u16[3]) == 0) && \
(((a)->u16[4]) == 0) && \
(((a)->u16[5]) == 0) && \
(((a)->u16[6]) == 0) && \
(((a)->u8[14]) == 0) && \
((((a)->u8[15]) == 1) || (((a)->u8[15]) == 2)))
/* FFXX::00XX:XXXX:XXXX */
#define SIXLOWPAN_IS_MCASTADDR_COMPRESSABLE48(a) \
((((a)->u16[1]) == 0) && \
(((a)->u16[2]) == 0) && \
(((a)->u16[3]) == 0) && \
(((a)->u16[4]) == 0) && \
(((a)->u8[10]) == 0))
/* FFXX::00XX:XXXX */
#define SIXLOWPAN_IS_MCASTADDR_COMPRESSABLE32(a) \
((((a)->u16[1]) == 0) && \
(((a)->u16[2]) == 0) && \
(((a)->u16[3]) == 0) && \
(((a)->u16[4]) == 0) && \
(((a)->u16[5]) == 0) && \
(((a)->u8[12]) == 0))
/* FF02::00XX */
#define SIXLOWPAN_IS_MCASTADDR_COMPRESSABLE8(a) \
((((a)->u8[1]) == 2) && \
(((a)->u16[1]) == 0) && \
(((a)->u16[2]) == 0) && \
(((a)->u16[3]) == 0) && \
(((a)->u16[4]) == 0) && \
(((a)->u16[5]) == 0) && \
(((a)->u16[6]) == 0) && \
(((a)->u8[14]) == 0))
/* This maximum size of an IEEE802.15.4 frame. Certain, non-standard
* devices may exceed this value, however.
*/
@@ -402,6 +336,7 @@ struct ieee802154_driver_s
FAR struct iob_s *i_framelist;
/* Driver Configuration ***************************************************/
/* i_panid. The PAN ID is 16-bit number that identifies the network. It
* must be unique to differentiate a network. All the nodes in the same
* network should have the same PAN ID. This value must be provided to
@@ -433,30 +368,42 @@ struct ieee802154_driver_s
*/
uint16_t i_dgramtag;
};
/* The structure of a next header compressor. This compressor is provided
* by architecture-specific logic outside of the network stack.
*
* TODO: needs more parameters when compressing extension headers, etc.
*/
struct sixlowpan_nhcompressor_s
{
CODE int (*is_compressable)(uint8_t next_header);
/* Compress next header (TCP/UDP, etc) - ptr points to next header to
* compress.
#if CONFIG_NET_6LOWPAN_FRAG
/* Fragmentation Support *************************************************/
/* Fragementation is handled frame by frame and requires that certain
* state information be retained from frame to frame.
*/
CODE int (*compress)(FAR uint8_t *compressed, FAR uint8_t *uncompressed_len);
/* Uncompress next header (TCP/UDP, etc) - ptr points to next header to
* uncompress.
/* i_pktlen. The total length of the IPv6 packet to be re-assembled in
* d_buf.
*/
CODE int (*uncompress)(FAR uint8_t *compressed, FAR uint8_t *lowpanbuf,
FAR uint8_t *uncompressed_len);
uint16_t i_pktlen;
/* The current accumulated length of the packet being received in d_buf.
* Included IPv6 and protocol headers.
*/
uint16_t i_accumlen;
/* i_reasstag. Each frame in the reassembly has a tag. That tag must
* match the reassembly tag in the fragments being merged.
*/
uint16_t i_reasstag;
/* The source MAC address of the fragments being merged */
struct rimeaddr_s i_fragsrc;
/* That time at which reassembly was started. If the elapsed time
* exceeds CONFIG_NET_6LOWPAN_MAXAGE, then the reassembly will
* be cancelled.
*/
systime_t i_time;
#endif /* CONFIG_NET_6LOWPAN_FRAG */
};
/****************************************************************************
@@ -518,21 +465,4 @@ struct sixlowpan_nhcompressor_s
int sixlowpan_input(FAR struct ieee802154_driver_s *ieee);
/****************************************************************************
* Function: sixlowpan_set_compressor
*
* Description:
* Configure to use the architecture-specific compressor.
*
* Input parameters:
* compressor - A reference to the new compressor to be used. This may
* be a NULL value to disable the compressor.
*
* Returned Value:
* None
*
****************************************************************************/
void sixlowpan_set_compressor(FAR struct sixlowpan_nhcompressor_s *compressor);
#endif /* __INCLUDE_NUTTX_NET_SIXLOWOAN_H */
+37 -1
View File
@@ -95,6 +95,7 @@
#include "neighbor/neighbor.h"
#include "tcp/tcp.h"
#include "udp/udp.h"
#include "sixlowpan/sixlowpan.h"
#include "pkt/pkt.h"
#include "icmpv6/icmpv6.h"
@@ -255,12 +256,45 @@ int ipv6_input(FAR struct net_driver_s *dev)
{
#ifdef NET_TCP_HAVE_STACK
case IP_PROTO_TCP: /* TCP input */
/* Forward the IPv6 TCP packet */
tcp_ipv6_input(dev);
break;
#ifdef CONFIG_NET_6LOWPAN
/* TCP output comes through two different mechansims. Either from:
*
* 1. TCP socket output. For the case of TCP output to an
* IEEE802.15.4, the TCP output is caught in the socket
* send()/sendto() logic and and redirected to 6loWPAN logic.
* 2. TCP output from the TCP state machine. That will pass
* here and can be detected if d_len > 0. It will be redirected
* to 6loWPAN logic here.
*/
#ifdef CONFIG_NET_MULTILINK
/* Handle the case where multiple link layer protocols are supported */
if (dev->d_len > 0 && dev->d_lltype == CONFIG_NET_6LOWPAN)
#else
if (dev->d_len > 0)
#endif
{
/* Let 6loWPAN handle the TCP output */
sixlowpan_tcp_send(dev);
/* Drop the packet in the d_buf */
goto drop;
}
#endif /* CONFIG_NET_6LOWPAN */
break;
#endif /* NET_TCP_HAVE_STACK */
#ifdef NET_UDP_HAVE_STACK
case IP_PROTO_UDP: /* UDP input */
/* Forward the IPv6 UDP packet */
udp_ipv6_input(dev);
break;
#endif
@@ -269,6 +303,8 @@ int ipv6_input(FAR struct net_driver_s *dev)
#ifdef CONFIG_NET_ICMPv6
case IP_PROTO_ICMP6: /* ICMP6 input */
/* Forward the ICMPv6 packet */
icmpv6_input(dev);
break;
#endif
+2 -1
View File
@@ -132,7 +132,8 @@ config NET_6LOWPAN_MAXAGE
int "Packet reassembly timeout"
default 20
---help---
Timeout for packet reassembly at the 6lowpan layer (should be < 60s)
Timeout for packet reassembly at the 6lowpan layer in units of
seconds (should be < 60s)
config NET_6LOWPAN_MAX_MACTRANSMITS
int "Max MAC transmissions"
+1 -1
View File
@@ -41,7 +41,7 @@ ifeq ($(CONFIG_NET_6LOWPAN),y)
NET_CSRCS += sixlowpan_initialize.c sixlowpan_globals.c sixlowpan_utils.c
NET_CSRCS += sixlowpan_input.c sixlowpan_send.c sixlowpan_framer.c
NET_CSRCS += sixlowpan_framelist.c sixlowpan_compressor.c
NET_CSRCS += sixlowpan_framelist.c
ifeq ($(CONFIG_NET_TCP),y)
NET_CSRCS += sixlowpan_tcpsend.c
+64 -1
View File
@@ -53,7 +53,9 @@
* Public Function Prototypes
****************************************************************************/
struct socket; /* Forward reference */
struct net_driver_s; /* Forward reference */
struct socket; /* Forward reference */
struct sockaddr; /* Forward reference */
/****************************************************************************
* Name: sixlowpan_initialize
@@ -104,6 +106,33 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
size_t len);
#endif
/****************************************************************************
* Function: sixlowpan_tcp_send
*
* Description:
* TCP output comes through two different mechansims. Either from:
*
* 1. TCP socket output. For the case of TCP output to an
* IEEE802.15.4, the TCP output is caught in the socket
* send()/sendto() logic and and redirected to psock_6lowpan_tcp_send().
* 2. TCP output from the TCP state machine. That will occur
* during TCP packet processing by the TCP state meachine. It
* is detected there when ipv6_tcp_input() returns with d_len > 0. This
* will be redirected here.
*
* Parameters:
* dev - An instance of nework device state structure
*
* Returned Value:
* None
*
* Assumptions:
* Called with the network locked.
*
****************************************************************************/
void sixlowpan_tcp_send(FAR struct net_driver_s *dev);
/****************************************************************************
* Function: psock_6lowpan_udp_send
*
@@ -132,5 +161,39 @@ ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf,
size_t len);
#endif
/****************************************************************************
* Function: psock_6lowpan_udp_sendto
*
* Description:
* If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET)
* socket, the parameters to and 'tolen' are ignored (and the error EISCONN
* may be returned when they are not NULL and 0), and the error ENOTCONN is
* returned when the socket was not actually connected.
*
* Parameters:
* psock A pointer to a NuttX-specific, internal socket structure
* buf Data to send
* len Length of data to send
* flags Send flags
* to Address of recipient
* tolen The length of the address structure
*
* Returned Value:
* On success, returns the number of characters sent. On error,
* -1 is returned, and errno is set appropriately. Returned error
* number must be consistent with definition of errors reported by
* sendto().
*
* Assumptions:
* Called with the network locked.
*
****************************************************************************/
ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock,
FAR const void *buf,
size_t len, int flags,
FAR const struct sockaddr *to,
socklen_t tolen);
#endif /* CONFIG_NET_6LOWPAN */
#endif /* _NET_SIXLOWPAN_SIXLOWPAN_H */
-79
View File
@@ -1,79 +0,0 @@
/****************************************************************************
* net/sixlowpan/sixlowpan_compressor.c
*
* Copyright (C) 2017 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>
#include "nuttx/net/net.h"
#include "sixlowpan/sixlowpan_internal.h"
#ifdef CONFIG_NET_6LOWPAN
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Function: sixlowpan_set_compressor
*
* Description:
* Configure to use the architecture-specific compressor.
*
* Input parameters:
* compressor - A reference to the new compressor to be used. This may
* be a NULL value to disable the compressor.
*
* Returned Value:
* None
*
****************************************************************************/
void sixlowpan_set_compressor(FAR struct sixlowpan_nhcompressor_s *compressor)
{
/* Make sure that the compressor is not in use */
net_lock();
/* Then instantiate the new compressor */
g_sixlowpan_compressor = compressor;
net_unlock();
}
#endif /* CONFIG_NET_6LOWPAN */
+27 -40
View File
@@ -100,8 +100,8 @@
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* Input Parameters:
* ieee - Pointer to IEEE802.15.4 MAC driver structure.
* ipv6 - Pointer to the IPv6 header to "compress"
* ieee - Pointer to IEEE802.15.4 MAC driver structure.
* destip - Pointer to the IPv6 header to "compress"
*
* Returned Value:
* None
@@ -109,7 +109,7 @@
****************************************************************************/
static void sixlowpan_compress_ipv6hdr(FAR struct ieee802154_driver_s *ieee,
FAR const struct ipv6_hdr_s *ipv6)
FAR const struct ipv6_hdr_s *destip)
{
/* Indicate the IPv6 dispatch and length */
@@ -118,7 +118,7 @@ static void sixlowpan_compress_ipv6hdr(FAR struct ieee802154_driver_s *ieee,
/* Copy the IPv6 header and adjust pointers */
memcpy(g_rimeptr + g_rime_hdrlen, ipv6, IPv6_HDRLEN);
memcpy(g_rimeptr + g_rime_hdrlen, destip, IPv6_HDRLEN);
g_rime_hdrlen += IPv6_HDRLEN;
g_uncomp_hdrlen += IPv6_HDRLEN;
}
@@ -161,12 +161,12 @@ static void sixlowpan_compress_ipv6hdr(FAR struct ieee802154_driver_s *ieee,
int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
FAR const struct ipv6_hdr_s *destip,
FAR const void *buf, size_t len,
FAR const void *buf, size_t len,
FAR const struct rimeaddr_s *destmac)
{
FAR struct iob_s *iob;
int framer_hdrlen;
struct rimeaddr_s dest;
struct rimeaddr_s bcastmac;
uint16_t outlen = 0;
/* Initialize global data. Locking the network guarantees that we have
@@ -211,13 +211,24 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
if (destmac == NULL)
{
memset(&dest, 0, sizeof(struct rimeaddr_s));
}
else
{
rimeaddr_copy(&dest, (FAR const struct rimeaddr_s *)destmac);
memset(&bcastmac, 0, sizeof(struct rimeaddr_s));
destmac = &bcastmac;
}
/* Pre-allocate the IOB to hold frame or the first fragment, waiting if
* necessary.
*/
iob = iob_alloc(false);
DEBUGASSERT(iob != NULL);
/* Initialize the IOB */
iob->io_flink = NULL;
iob->io_len = 0;
iob->io_offset = 0;
iob->io_pktlen = 0;
ninfo("Sending packet len %d\n", len);
#ifndef CONFIG_NET_6LOWPAN_COMPRESSION_IPv6
@@ -226,9 +237,9 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
/* Try to compress the headers */
#if defined(CONFIG_NET_6LOWPAN_COMPRESSION_HC1)
sixlowpan_compresshdr_hc1(ieee, &dest);
sixlowpan_compresshdr_hc1(ieee, destip, destmac, iob);
#elif defined(CONFIG_NET_6LOWPAN_COMPRESSION_HC06)
sixlowpan_compresshdr_hc06(ieee, &dest);
sixlowpan_compresshdr_hc06(ieee, destip, destmac, iob);
#else
# error No compression specified
#endif
@@ -243,7 +254,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
ninfo("Header of len %d\n", g_rime_hdrlen);
rimeaddr_copy(&g_pktaddrs[PACKETBUF_ADDR_RECEIVER], &dest);
rimeaddr_copy(&g_pktaddrs[PACKETBUF_ADDR_RECEIVER], destmac);
/* Pre-calculate frame header length. */
@@ -279,20 +290,8 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
ninfo("Fragmentation sending packet len %d\n", len);
/* Allocate an IOB to hold the first fragment, waiting if necessary. */
iob = iob_alloc(false);
DEBUGASSERT(iob != NULL);
/* Initialize the IOB */
iob->io_flink = NULL;
iob->io_len = 0;
iob->io_offset = 0;
iob->io_pktlen = 0;
/* Create 1st Fragment */
/* Add the frame header */
/* Add the frame header using the pre-allocated IOB. */
verify = sixlowpan_framecreate(ieee, iob, ieee->i_panid);
DEBUGASSERT(verify == framer_hdrlen);
@@ -434,19 +433,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
* and send in one frame.
*/
/* Allocate an IOB to hold the frame, waiting if necessary. */
iob = iob_alloc(false);
DEBUGASSERT(iob != NULL);
/* Initialize the IOB */
iob->io_flink = NULL;
iob->io_len = 0;
iob->io_offset = 0;
iob->io_pktlen = 0;
/* Add the frame header */
/* Add the frame header to the prealloated IOB. */
verify = sixlowpan_framecreate(ieee, iob, ieee->i_panid);
DEBUGASSERT(vreify == framer_hdrlen);
-4
View File
@@ -47,10 +47,6 @@
* Public Data
****************************************************************************/
/* A pointer to the optional, architecture-specific compressor */
FAR struct sixlowpan_nhcompressor_s *g_sixlowpan_compressor;
/* The following data values are used to hold intermediate settings while
* processing IEEE802.15.4 frames. These globals are shared with incoming
* and outgoing frame processing and possibly with mutliple IEEE802.15.4 MAC
File diff suppressed because it is too large Load Diff
+235 -9
View File
@@ -53,6 +53,17 @@
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Buffer access helpers */
#define IPv6BUF(dev) \
((FAR struct ipv6_hdr_s *)((dev)->d_buf))
#define UDPIPv6BUF(dev) \
((FAR struct udp_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev) + IPv6_HDRLEN])
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -102,9 +113,11 @@
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* Input Parmeters:
* ieee - A reference to the IEE802.15.4 network device state
* destaddr - L2 destination address, needed to compress the IP
* destination field
* ieee - A reference to the IEE802.15.4 network device state
* ipv6 - The IPv6 header to be compressed
* destmac - L2 destination address, needed to compress the IP
* destination field
* iob - The IOB into which the compressed header should be saved.
*
* Returned Value:
* None
@@ -112,9 +125,109 @@
****************************************************************************/
void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
FAR struct rimeaddr_s *destaddr)
FAR const struct ipv6_hdr_s *ipv6,
FAR const struct rimeaddr_s *destmac,
FAR struct iob_s *iob)
{
/* REVISIT: To be provided */
FAR uint8_t *hc1 = RIME_HC1_PTR;
/* Check if all the assumptions for full compression are valid */
if (ipv6->vtc != 0x60 || ipv6->tcflow != 0 || ipv6->flow != 0 ||
!sixlowpan_islinklocal(&ipv6->srcipaddr) ||
!sixlowpan_ismacbased(&ipv6->srcipaddr, &ieee->i_rimeaddr) ||
!sixlowpan_islinklocal(&ipv6->destipaddr) ||
!sixlowpan_ismacbased(&ipv6->destipaddr, destmac) ||
(ipv6->proto != IP_PROTO_ICMP6 && ipv6->proto != IP_PROTO_UDP &&
ipv6->proto != IP_PROTO_TCP))
{
/* IPV6 DISPATCH
* Something cannot be compressed, use IPV6 DISPATCH,
* compress nothing, copy IPv6 header in rime buffer
*/
*g_rimeptr = SIXLOWPAN_DISPATCH_IPV6;
g_rime_hdrlen += SIXLOWPAN_IPV6_HDR_LEN;
memcpy(g_rimeptr + g_rime_hdrlen, ipv6, IPv6_HDRLEN);
g_rime_hdrlen += IPv6_HDRLEN;
g_uncomp_hdrlen += IPv6_HDRLEN;
}
else
{
/* HC1 DISPATCH maximum compresssion:
* All fields in the IP header but Hop Limit are elided. If next
* header is UDP, we compress UDP header using HC2
*/
hc1[RIME_HC1_DISPATCH] = SIXLOWPAN_DISPATCH_HC1;
g_uncomp_hdrlen += IPv6_HDRLEN;
switch (ipv6->proto)
{
case IP_PROTO_ICMP6:
/* HC1 encoding and ttl */
hc1[RIME_HC1_ENCODING] = 0xfc;
hc1[RIME_HC1_TTL] = ipv6->ttl;
g_rime_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
break;
#if CONFIG_NET_TCP
case IP_PROTO_TCP:
/* HC1 encoding and ttl */
hc1[RIME_HC1_ENCODING] = 0xfe;
hc1[RIME_HC1_TTL] = ipv6->ttl;
g_rime_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
break;
#endif /* CONFIG_NET_TCP */
#if CONFIG_NET_UDP
case IP_PROTO_UDP:
FAR struct udp_hdr_s *udp = UDPIPv6BUF(dev);
/* Try to compress UDP header (we do only full compression). This
* is feasible if both src and dest ports are between
* SIXLOWPAN_UDP_PORT_MIN and SIXLOWPAN_UDP_PORT_MIN + 15
*/
ninfo("local/remote port %u/%u\n", udp->srcport, udp->destport);
if (htons(udp->srcport) >= SIXLOWPAN_UDP_PORT_MIN &&
htons(udp->srcport) < SIXLOWPAN_UDP_PORT_MAX &&
htons(udp->destport) >= SIXLOWPAN_UDP_PORT_MIN &&
htons(udp->destport) < SIXLOWPAN_UDP_PORT_MAX)
{
FAR uint8_t *hcudp = RIME_HC1_HC_UDP_PTR;
/* HC1 encoding */
hcudp[RIME_HC1_HC_UDP_HC1_ENCODING] = 0xfb;
/* HC_UDP encoding, ttl, src and dest ports, checksum */
hcudp[RIME_HC1_HC_UDP_UDP_ENCODING] = 0xe0;
hcudp[RIME_HC1_HC_UDP_TTL] = ipv6->ttl;
hcudp[RIME_HC1_HC_UDP_PORTS] =
(uint8_t)((htons(udp->srcport) - SIXLOWPAN_UDP_PORT_MIN) << 4) +
(uint8_t)((htons(udp->destport) - SIXLOWPAN_UDP_PORT_MIN));
memcpy(&hcudp[RIME_HC1_HC_UDP_CHKSUM], &udp->udpchksum, 2);
g_rime_hdrlen += SIXLOWPAN_HC1_HC_UDP_HDR_LEN;
g_uncomp_hdrlen += UIP_UDPH_LEN;
}
else
{
/* HC1 encoding and ttl */
hc1[RIME_HC1_ENCODING] = 0xfa;
hc1[RIME_HC1_TTL] = ipv6->ttl;
g_rime_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
}
break;
#endif /* CONFIG_NET_UDP */
}
}
}
/****************************************************************************
@@ -136,14 +249,127 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
* fragment.
*
* Returned Value:
* None
* Zero (OK) is returned on success, on failure a negater errno value is
* returned.
*
****************************************************************************/
void sixlowpan_uncompresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
uint16_t iplen)
int sixlowpan_uncompresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
uint16_t iplen)
{
/* REVISIT: To be provided */
FAR struct ipv6_hdr_s *ipv6 = IPv6BUF(&ieee->i_dev);
FAR uint8_t *hc1 = RIME_HC1_PTR;
/* Format the IPv6 header in the device d_buf */
/* Set version, traffic clase, and flow label */
ipv6->vtc = 0x60; /* Bits 0-3: version, bits 4-7: traffic class (MS) */
ipv6->tcf = 0; /* Bits 0-3: traffic class (LS), 4-bits: flow label (MS) */
ipv6->flow = 0; /* 16-bit flow label (LS) */
/* Use stateless auto-configuration to set source and destination IP
* addresses.
*/
sixlowpan_ipfromrime(&g_pktaddrs[PACKETBUF_ADDR_SENDER],
&ipv6->srcipaddr);
sixlowpan_ipfromrime(&g_pktaddrs[PACKETBUF_ADDR_RECEIVER],
&ipv6->destipaddr);
g_uncomp_hdrlen += IPv6_HDRLEN;
/* len[], proto, and ttl depend on the encoding */
switch (hc1[RIME_HC1_ENCODING] & 0x06)
{
case SIXLOWPAN_HC1_NH_ICMP6:
ipv6->proto = IP_PROTO_ICMP6;
ipv6->ttl = hc1[RIME_HC1_TTL];
g_rime_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
break;
#if CONFIG_NET_TCP
case SIXLOWPAN_HC1_NH_TCP:
ipv6->proto = IP_PROTO_TCP;
ipv6->ttl = hc1[RIME_HC1_TTL];
g_rime_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
break;
#endif /* CONFIG_NET_TCP */
#if CONFIG_NET_UDP
case SIXLOWPAN_HC1_NH_UDP:
{
FAR struct udp_hdr_s *udp = UDPIPv6BUF(&ieee->i_dev);
FAR uint8_t *hcudp = RIME_HC1_HC_UDP_PTR;
ipv6->proto = IP_PROTO_UDP;
if ((hcudp[RIME_HC1_HC_UDP_HC1_ENCODING] & 0x01) != 0)
{
/* UDP header is compressed with HC_UDP */
if (hcudp[RIME_HC1_HC_UDP_UDP_ENCODING] !=
SIXLOWPAN_HC_UDP_ALL_C)
{
nwarn("WARNING: sixlowpan (uncompress_hdr), packet not supported");
return -EOPNOTSUPP;
}
/* IP TTL */
ipv6->ttl = hcudp[RIME_HC1_HC_UDP_TTL];
/* UDP ports, len, checksum */
udp->srcport =
htons(SIXLOWPAN_UDP_PORT_MIN + (hcudp[RIME_HC1_HC_UDP_PORTS] >> 4));
udp->destport =
htons(SIXLOWPAN_UDP_PORT_MIN + (hcudp[RIME_HC1_HC_UDP_PORTS] & 0x0F));
memcpy(&udp->udpchksum, &hcudp[RIME_HC1_HC_UDP_CHKSUM], 2);
g_uncomp_hdrlen += UIP_UDPH_LEN;
g_rime_hdrlen += SIXLOWPAN_HC1_HC_UDP_HDR_LEN;
}
else
{
g_rime_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
}
}
break;
#endif /* CONFIG_NET_UDP */
default:
return -EPROTONOSUPPORT;
}
/* IP length field. */
if (iplen == 0)
{
/* This is not a fragmented packet */
ipv6->len[0] = 0;
ipv6->len[1] = ieee->i_dev.d_len - g_rime_hdrlen + /* REVISIT */
g_uncomp_hdrlen - IPv6_HDRLEN;
}
else
{
/* This is a 1st fragment */
ipv6->len[0] = (iplen - IPv6_HDRLEN) >> 8;
ipv6->len[1] = (iplen - IPv6_HDRLEN) & 0x00FF;
}
/* length field in UDP header */
#if CONFIG_NET_UDP
if (ipv6->proto == IP_PROTO_UDP)
{
FAR struct udp_hdr_s *udp = UDPIPv6BUF(&ieee->i_dev);
memcpy(&udp->udplen, &ipv6->len[0], 2);
}
#endif
return;
}
#endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC1 */
File diff suppressed because it is too large Load Diff
+122 -25
View File
@@ -89,7 +89,7 @@
* The fragment header is used when the payload is too large to fit in a
* single IEEE 802.15.4 frame. The fragment header contains three fields:
* Datagram size, datagram tag and datagram offset.
*
*
* 1. Datagram size describes the total (un-fragmented) payload.
* 2. Datagram tag identifies the set of fragments and is used to match
* fragments of the same payload.
@@ -225,10 +225,72 @@
#define FRAME_SIZE(ieee,iob) \
((iob)->io_len)
/* Address compressibility test macros **************************************/
/* Check whether we can compress the IID in address 'a' to 16 bits. This is
* used for unicast addresses only, and is true if the address is on the
* format <PREFIX>::0000:00ff:fe00:XXXX
*
* NOTE: we currently assume 64-bits prefixes
*/
/* Check whether we can compress the IID in address 'a' to 16 bits. This is
* used for unicast addresses only, and is true if the address is on the
* format <PREFIX>::0000:00ff:fe00:XXXX.
*
* NOTE: we currently assume 64-bits prefixes. Big-endian, network order is
* assumed.
*/
#define SIXLOWPAN_IS_IID_16BIT_COMPRESSABLE(a) \
((((a)[4]) == 0x0000) && (((a)[5]) == 0x00ff) && (((a)[6]) == 0xfe00))
/* Check whether the 9-bit group-id of the compressed multicast address is
* known. It is true if the 9-bit group is the all nodes or all routers
* group. Parameter 'a' is typed uint8_t *
*/
#define SIXLOWPAN_IS_MCASTADDR_DECOMPRESSABLE(a) \
(((*a & 0x01) == 0) && \
((*(a + 1) == 0x01) || (*(a + 1) == 0x02)))
/* Check whether the 112-bit group-id of the multicast address is mappable
* to a 9-bit group-id. It is true if the group is the all nodes or all
* routers group:
*
* XXXX:0000:0000:0000:0000:0000:0000:0001 All nodes address
* XXXX:0000:0000:0000:0000:0000:0000:0002 All routers address
*/
#define SIXLOWPAN_IS_MCASTADDR_COMPRESSABLE(a) \
((a)[1] == 0 && (a)[2] == 0 && (a)[3] == 0 && \
(a)[4] == 0 && (a)[5] == 0 && (a)[6] == 0 && \
((a)[7] == 0x0001 || (a)[7] == 0x0002))
/* FFXX:0000:0000:0000:0000:00XX:XXXX:XXXX */
#define SIXLOWPAN_IS_MCASTADDR_COMPRESSABLE48(a) \
((a)[1] == 0 && (a)[2] == 0 && (a)[3] == 0 && \
(a)[4] == 0 && (((a)[5] & 0xff00) == 0))
/* FFXX:0000:0000:0000:0000:0000:00XX:XXXX */
#define SIXLOWPAN_IS_MCASTADDR_COMPRESSABLE32(a) \
((a)[1] == 0 && (a)[2] == 0 && (a)[3] == 0 && \
(a)[4] == 0 && (a)[5] == 0 && ((a)[6] & 0xff00) == 0)
/* FF02:0000:0000:0000:0000:0000:0000:00XX */
#define SIXLOWPAN_IS_MCASTADDR_COMPRESSABLE8(a) \
((((a)[0] & 0x00ff) == 0x0002) && \
(a)[1] == 0 && (a)[2] == 0 && (a)[3] == 0 && \
(a)[4] == 0 && (a)[5] == 0 && (a)[6] == 0 && \
(((a)[7] & 0xff00) == 0x0000))
/* General helper macros ****************************************************/
#define GETINT16(ptr,index) \
((((uint16_t)((ptr)[index]) << 8)) | ((uint16_t)(((ptr)[(index) + 1]))))
((((uint16_t)((ptr)[index])) << 8) | ((uint16_t)(((ptr)[(index) + 1]))))
#define PUTINT16(ptr,index,value) \
do \
{ \
@@ -335,11 +397,6 @@ struct frame802154_s
* Public Data
****************************************************************************/
/* A pointer to the optional, architecture-specific compressor */
struct sixlowpan_nhcompressor_s; /* Foward reference */
extern FAR struct sixlowpan_nhcompressor_s *g_sixlowpan_compressor;
/* The following data values are used to hold intermediate settings while
* processing IEEE802.15.4 frames. These globals are shared with incoming
* and outgoing frame processing and possibly with mutliple IEEE802.15.4 MAC
@@ -396,6 +453,7 @@ extern struct rimeaddr_s g_pktaddrs[PACKETBUF_NUM_ADDRS];
struct net_driver_s; /* Forward reference */
struct ieee802154_driver_s; /* Forward reference */
struct ipv6_hdr_s; /* Forward reference */
struct rimeaddr_s; /* Forward reference */
struct iob_s; /* Forward reference */
@@ -407,7 +465,7 @@ struct iob_s; /* Forward reference */
* it to be sent on an 802.15.4 network using 6lowpan. Called from common
* UDP/TCP send logic.
*
* The payload data is in the caller 'buf' and is of length 'len'.
* The payload data is in the caller 'buf' and is of length 'buflen'.
* Compressed headers will be added and if necessary the packet is
* fragmented. The resulting packet/fragments are put in ieee->i_framelist
* and the entire list of frames will be delivered to the 802.15.4 MAC via
@@ -415,9 +473,9 @@ struct iob_s; /* Forward reference */
*
* Input Parameters:
* dev - The IEEE802.15.4 MAC network driver interface.
* ipv6 - IPv6 plus TCP or UDP headers.
* destip - IPv6 plus TCP or UDP headers.
* buf - Data to send
* len - Length of data to send
* buflen - Length of data to send
* raddr - The MAC address of the destination
* timeout - Send timeout in deciseconds
*
@@ -433,8 +491,8 @@ struct iob_s; /* Forward reference */
****************************************************************************/
int sixlowpan_send(FAR struct net_driver_s *dev,
FAR const struct ipv6_hdr_s *ipv6, FAR const void *buf,
size_t len, FAR const struct rimeaddr_s *raddr,
FAR const struct ipv6_hdr_s *destip, FAR const void *buf,
size_t buflen, FAR const struct rimeaddr_s *raddr,
uint16_t timeout);
/****************************************************************************
@@ -499,7 +557,7 @@ int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee,
* ieee - The IEEE802.15.4 MAC driver instance
* ipv6hdr - IPv6 header followed by TCP or UDP header.
* buf - Data to send
* len - Length of data to send
* buflen - Length of data to send
* destmac - The IEEE802.15.4 MAC address of the destination
*
* Returned Value:
@@ -515,7 +573,7 @@ int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee,
int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
FAR const struct ipv6_hdr_s *ipv6hdr,
FAR const void *buf, size_t len,
FAR const void *buf, size_t buflen,
FAR const struct rimeaddr_s *destmac);
/****************************************************************************
@@ -542,7 +600,7 @@ void sixlowpan_hc06_initialize(void);
#endif
/****************************************************************************
* Name: sixlowpan_hc06_initialize
* Name: sixlowpan_compresshdr_hc06
*
* Description:
* Compress IP/UDP header
@@ -559,7 +617,10 @@ void sixlowpan_hc06_initialize(void);
*
* Input Parameters:
* ieee - A reference to the IEE802.15.4 network device state
* destaddr - L2 destination address, needed to compress IP dest
* ipv6 - The IPv6 header to be compressed
* destmac - L2 destination address, needed to compress the IP
* destination field
* iob - The IOB into which the compressed header should be saved.
*
* Returned Value:
* None
@@ -567,12 +628,14 @@ void sixlowpan_hc06_initialize(void);
****************************************************************************/
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *dev,
FAR struct rimeaddr_s *destaddr);
void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
FAR const struct ipv6_hdr_s *ipv6,
FAR const struct rimeaddr_s *destmac,
FAR struct iob_s *iob);
#endif
/****************************************************************************
* Name: sixlowpan_hc06_initialize
* Name: sixlowpan_uncompresshdr_hc06
*
* Description:
* Uncompress HC06 (i.e., IPHC and LOWPAN_UDP) headers and put them in
@@ -587,7 +650,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *dev,
* Input Parmeters:
* ieee - A reference to the IEE802.15.4 network device state
* iplen - Equal to 0 if the packet is not a fragment (IP length is then
* inferred from the L2 length), non 0 if the packet is a 1st
* inferred from the L2 length), non 0 if the packet is a first
* fragment.
*
* Returned Value:
@@ -611,9 +674,11 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
* uip_buf buffer.
*
* Input Parmeters:
* ieee - A reference to the IEE802.15.4 network device state
* destaddr - L2 destination address, needed to compress the IP
* destination field
* ieee - A reference to the IEE802.15.4 network device state
* ipv6 - The IPv6 header to be compressed
* destmac - L2 destination address, needed to compress the IP
* destination field
* iob - The IOB into which the compressed header should be saved.
*
* Returned Value:
* None
@@ -622,7 +687,9 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1
void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
FAR struct rimeaddr_s *destaddr);
FAR const struct ipv6_hdr_s *ipv6,
FAR const struct rimeaddr_s *destmac,
FAR struct iob_s *iob);
#endif
/****************************************************************************
@@ -640,7 +707,7 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
* Input Parameters:
* ieee - A reference to the IEE802.15.4 network device state
* iplen - Equal to 0 if the packet is not a fragment (IP length is then
* inferred from the L2 length), non 0 if the packet is a 1st
* inferred from the L2 length), non 0 if the packet is a first
* fragment.
*
* Returned Value:
@@ -663,5 +730,35 @@ void sixlowpan_uncompresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
int sixlowpan_frame_hdralloc(FAR struct iob_s *iob, int size);
/****************************************************************************
* Name: sixlowpan_islinklocal, sixlowpan_ipfromrime, sixlowpan_rimefromip,
* and sixlowpan_ismacbased
*
* Description:
* sixlowpan_ipfromrime: Create a link local IPv6 address from a rime
* address.
*
* sixlowpan_rimefromip: Extract the rime address from a link local IPv6
* address.
*
* sixlowpan_islinklocal and sixlowpan_ismacbased will return true for
* address created in this fashion.
*
* 128 112 96 80 64 48 32 16
* ---- ---- ---- ---- ---- ---- ---- ----
* fe80 0000 0000 0000 xxxx 0000 0000 0000 2-byte Rime address (VALID?)
* fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte Rime address
*
****************************************************************************/
#define sixlowpan_islinklocal(ipaddr) ((ipaddr)[0] = NTOHS(0xfe80))
void sixlowpan_ipfromrime(FAR const struct rimeaddr_s *rime,
net_ipv6addr_t ipaddr);
void sixlowpan_rimefromip(const net_ipv6addr_t ipaddr,
FAR struct rimeaddr_s *rime);
bool sixlowpan_ismacbased(const net_ipv6addr_t ipaddr,
FAR const struct rimeaddr_s *rime);
#endif /* CONFIG_NET_6LOWPAN */
#endif /* _NET_SIXLOWPAN_SIXLOWPAN_INTERNAL_H */
+13
View File
@@ -54,6 +54,17 @@
#ifdef CONFIG_NET_6LOWPAN
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* These are temporary stubs. Something like this would be needed to
* monitor the health of a IPv6 neighbor.
*/
#define neighbor_reachable(dev)
#define neighbor_notreachable(dev)
/****************************************************************************
* Private Types
****************************************************************************/
@@ -172,6 +183,7 @@ static uint16_t send_interrupt(FAR struct net_driver_s *dev,
sinfo->s_destmac);
flags &= ~WPAN_POLL;
neighbor_reachable(dev);
goto end_wait;
}
@@ -183,6 +195,7 @@ static uint16_t send_interrupt(FAR struct net_driver_s *dev,
nwarn("WARNING: SEND timeout\n");
sinfo->s_result = -ETIMEDOUT;
neighbor_notreachable(dev);
goto end_wait;
}
+166 -7
View File
@@ -39,11 +39,13 @@
#include <nuttx/config.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include "nuttx/net/netdev.h"
#include "nuttx/net/netstats.h"
#include "netdev/netdev.h"
#include "socket/socket.h"
@@ -66,7 +68,7 @@
* Parameters:
* psock - An instance of the internal socket structure.
* buf - Data to send
* len - Length of data to send
* bulen - Length of data to send
*
* Returned Value:
* On success, returns the number of characters sent. On error,
@@ -80,13 +82,14 @@
****************************************************************************/
ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
size_t len)
size_t buflen)
{
FAR struct tcp_conn_s *conn;
FAR struct net_driver_s *dev;
struct ipv6tcp_hdr_s ipv6tcp;
struct rimeaddr_s destmac;
uint16_t timeout;
uint16_t iplen;
int ret;
DEBUGASSERT(psock != NULL && psock->s_crefs > 0);
@@ -113,7 +116,7 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
conn = (FAR struct tcp_conn_s *)psock->s_conn;
DEBUGASSERT(conn != NULL);
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
#ifdef CONFIG_NET_IPv4
/* Ignore if not IPv6 domain */
if (conn->domain != PF_INET6)
@@ -161,14 +164,88 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
#endif
/* Initialize the IPv6/TCP headers */
#warning Missing logic
/* Initialize the IPv6/UDP headers */
ipv6tcp.ipv6.vtc = 0x60;
ipv6tcp.ipv6.tcf = 0x00;
ipv6tcp.ipv6.flow = 0x00;
ipv6tcp.ipv6.proto = IP_PROTO_TCP;
ipv6tcp.ipv6.ttl = IP_TTL;
/* The IPv6 header length field does not include the size of IPv6 IP
* header.
*/
iplen = buflen + TCP_HDRLEN;
ipv6tcp.ipv6.len[0] = (iplen >> 8);
ipv6tcp.ipv6.len[1] = (iplen & 0xff);
/* Copy the source and destination addresses */
net_ipv6addr_hdrcopy(ipv6tcp.ipv6.srcipaddr, conn->u.ipv6.laddr);
net_ipv6addr_hdrcopy(ipv6tcp.ipv6.destipaddr, conn->u.ipv6.raddr);
ninfo("IPv6 length: %d\n", ((int)ipv6->len[0] << 8) + ipv6->len[1]);
#ifdef CONFIG_NET_STATISTICS
g_netstats.ipv6.sent++;
#endif
/* Initialize the TCP header */
ipv6tcp.tcp.srcport = conn->lport; /* Local port */
ipv6tcp.tcp.destport = conn->rport; /* Connected remote port */
memcpy(ipv6tcp.tcp.ackno, conn->rcvseq, 4); /* ACK number */
memcpy(ipv6tcp.tcp.seqno, conn->sndseq, 4); /* Sequence number */
ipv6tcp.tcp.tcpoffset = (TCP_HDRLEN / 4) << 4; /* No optdata */
ipv6tcp.tcp.urgp[0] = 0; /* No urgent data */
ipv6tcp.tcp.urgp[1] = 0;
/* Set the TCP window */
if (conn->tcpstateflags & TCP_STOPPED)
{
/* If the connection has issued TCP_STOPPED, we advertise a zero
* window so that the remote host will stop sending data.
*/
ipv6tcp.tcp.wnd[0] = 0;
ipv6tcp.tcp.wnd[1] = 0;
}
else
{
ipv6tcp.tcp.wnd[0] = ((NET_DEV_RCVWNDO(dev)) >> 8);
ipv6tcp.tcp.wnd[1] = ((NET_DEV_RCVWNDO(dev)) & 0xff);
}
/* Calculate TCP checksum. */
ipv6tcp.tcp.tcpchksum = 0;
#if 0
/* REVISIT: Current checksum logic expects the IPv6 header, the UDP header, and
* the payload data to be in contiguous memory.
*/
ipv6tcp.tcp.tcpchksum = ~tcp_ipv6_chksum(dev);
#endif
ninfo("Outgoing TCP packet length: %d bytes\n", iplen + IOPv6_HDRLEN);
#ifdef CONFIG_NET_STATISTICS
g_netstats.tcp.sent++;
#endif
/* Set the socket state to sending */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
/* Get the Rime MAC address of the destination */
#warning Missing logic
/* Get the Rime MAC address of the destination This assumes an encoding
* of the MAC address in the IPv6 address.
*/
sixlowpan_rimefromip(conn->u.ipv6.raddr, &destmac);
/* If routable, then call sixlowpan_send() to format and send the 6loWPAN
* packet.
@@ -181,7 +258,7 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
#endif
ret = sixlowpan_send(dev, (FAR const struct ipv6_hdr_s *)&ipv6tcp,
buf, len, &destmac, timeout);
buf, buflen, &destmac, timeout);
if (ret < 0)
{
nerr("ERROR: sixlowpan_send() failed: %d\n", ret);
@@ -193,4 +270,86 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
return ret;
}
/****************************************************************************
* Function: sixlowpan_tcp_send
*
* Description:
* TCP output comes through two different mechansims. Either from:
*
* 1. TCP socket output. For the case of TCP output to an
* IEEE802.15.4, the TCP output is caught in the socket
* send()/sendto() logic and and redirected to psock_6lowpan_tcp_send().
* 2. TCP output from the TCP state machine. That will occur
* during TCP packet processing by the TCP state meachine. It
* is detected there when ipv6_tcp_input() returns with d_len > 0. This
* will be redirected here.
*
* Parameters:
* dev - An instance of nework device state structure
*
* Returned Value:
* None
*
* Assumptions:
* Called with the network locked.
*
****************************************************************************/
void sixlowpan_tcp_send(FAR struct net_driver_s *dev)
{
DEBUGASSERT(dev != NULL && dev->d_len > 0);
/* Double check */
if (dev != NULL && dev->d_len > 0)
{
FAR struct ipv6_hdr_s *ipv6hdr;
/* The IPv6 header followed by a TCP headers should lie at the
* beginning of d_buf since there is no link layer protocol header
* and the TCP state machine should only response with TCP packets.
*/
ipv6hdr = (FAR struct ipv6_hdr_s *)(dev->d_buf);
/* The TCP data payload should follow the IPv6 header plus the
* protocol header.
*/
if (ipv6hdr->proto != IP_PROTO_TCP)
{
nwarn("WARNING: Expected TCP protoype: %u\n", ipv6hdr->proto);
}
else
{
size_t hdrlen;
hdrlen = IPv6_HDRLEN + TCP_HDRLEN;
if (hdrlen < dev->d_len)
{
nwarn("WARNING: Packet to small: Have %u need >%u\n",
dev->d_len, hdrlen);
}
else
{
struct rimeaddr_s destmac;
/* Get the Rime MAC address of the destination. This assumes
* an encoding of the MAC address in the IPv6 address.
*/
sixlowpan_rimefromip(ipv6hdr->destipaddr, &destmac);
/* Convert the outgoing packet into a frame list. */
(void)sixlowpan_queue_frames(
(FAR struct ieee802154_driver_s *)dev, ipv6hdr,
dev->d_buf + hdrlen, dev->d_len - hdrlen, &destmac);
}
}
}
dev->d_len = 0;
}
#endif /* CONFIG_NET_6LOWPAN && CONFIG_NET_TCP */
+224 -78
View File
@@ -39,11 +39,14 @@
#include <nuttx/config.h>
#include <sys/socket.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include "nuttx/net/netdev.h"
#include "nuttx/net/netstats.h"
#include "netdev/netdev.h"
#include "socket/socket.h"
@@ -57,21 +60,26 @@
****************************************************************************/
/****************************************************************************
* Function: psock_6lowpan_udp_send
* Function: psock_6lowpan_udp_sendto
*
* Description:
* psock_6lowpan_udp_send() call may be used with connectionlesss UDP
* sockets.
* If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET)
* socket, the parameters to and 'tolen' are ignored (and the error EISCONN
* may be returned when they are not NULL and 0), and the error ENOTCONN is
* returned when the socket was not actually connected.
*
* Parameters:
* psock - An instance of the internal socket structure.
* buf - Data to send
* len - Length of data to send
* psock A pointer to a NuttX-specific, internal socket structure
* buf Data to send
* buflen Length of data to send
* flags Send flags
* to Address of recipient
* tolen The length of the address structure
*
* Returned Value:
* On success, returns the number of characters sent. On error,
* -1 is returned, and errno is set appropriately. Returned error numbers
* must be consistent with definition of errors reported by send() or
* -1 is returned, and errno is set appropriately. Returned error
* number must be consistent with definition of errors reported by
* sendto().
*
* Assumptions:
@@ -79,16 +87,215 @@
*
****************************************************************************/
ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf,
size_t len)
ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock,
FAR const void *buf,
size_t buflen, int flags,
FAR const struct sockaddr *to,
socklen_t tolen)
{
FAR struct sockaddr_in6 *to6 = (FAR struct sockaddr_in6 *)to;
FAR struct udp_conn_s *conn;
FAR struct net_driver_s *dev;
struct ipv6udp_hdr_s ipv6udp;
struct rimeaddr_s destmac;
uint16_t iplen;
uint16_t timeout;
int ret;
DEBUGASSERT(psock != NULL && psock->s_crefs > 0 && to != NULL);
DEBUGASSERT(psock->s_type == SOCK_DGRAM);
if (psock == NULL || to == NULL)
{
return (ssize_t)-EINVAL;
}
/* Make sure that this is a datagram valid socket */
if (psock->s_crefs <= 0 || psock->s_type != SOCK_DGRAM)
{
nerr("ERROR: Invalid socket\n");
return (ssize_t)-EBADF;
}
/* Make sure that the destination address is valid */
if (to6->sin6_family != AF_INET6 || tolen < sizeof(struct sockaddr_in6))
{
nerr("ERROR: Invalid destination address\n");
return (ssize_t)-EAFNOSUPPORT;
}
/* Get the underlying UDP "connection" structure */
conn = (FAR struct udp_conn_s *)psock->s_conn;
DEBUGASSERT(conn != NULL);
/* Ignore if not IPv6 domain */
if (conn->domain != PF_INET6)
{
nwarn("WARNING: Not IPv6\n");
return (ssize_t)-EPROTOTYPE;
}
/* Route outgoing message to the correct device */
#ifdef CONFIG_NETDEV_MULTINIC
dev = netdev_findby_ipv6addr(conn->u.ipv6.laddr,
to6->sin6_addr.in6_u.u6_addr16);
#ifdef CONFIG_NETDEV_MULTILINK
if (dev == NULL || dev->d_lltype != NET_LL_IEEE802154)
#else
if (dev == NULL)
#endif
{
nwarn("WARNING: Not routable or not IEEE802.15.4 MAC\n");
return (ssize_t)-ENETUNREACH;
}
#else
dev = netdev_findby_ipv6addr(to6->sin6_addr.in6_u.u6_addr16);
#ifdef CONFIG_NETDEV_MULTILINK
if (dev == NULL || dev->d_lltype != NET_LL_IEEE802154)
#else
if (dev == NULL)
#endif
{
nwarn("WARNING: Not routable\n");
return (ssize_t)-ENETUNREACH;
}
#endif
#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
/* Make sure that the IP address mapping is in the Neighbor Table */
ret = icmpv6_neighbor(to6->sin6_addr.in6_u.u6_addr16);
if (ret < 0)
{
nerr("ERROR: Not reachable\n");
return (ssize_t)-ENETUNREACH;
}
#endif
/* Initialize the IPv6/UDP headers */
ipv6udp.ipv6.vtc = 0x60;
ipv6udp.ipv6.tcf = 0x00;
ipv6udp.ipv6.flow = 0x00;
ipv6udp.ipv6.proto = IP_PROTO_UDP;
ipv6udp.ipv6.ttl = conn->ttl;
/* The IPv6 header length field does not include the size of IPv6 IP
* header.
*/
iplen = buflen + UDP_HDRLEN;
ipv6udp.ipv6.len[0] = (iplen >> 8);
ipv6udp.ipv6.len[1] = (iplen & 0xff);
/* Copy the source and destination addresses */
net_ipv6addr_hdrcopy(ipv6udp.ipv6.srcipaddr, to6->sin6_addr.in6_u.u6_addr16);
net_ipv6addr_hdrcopy(ipv6udp.ipv6.destipaddr, conn->u.ipv6.raddr);
ninfo("IPv6 length: %d\n", ((int)ipv6->len[0] << 8) + ipv6->len[1]);
#ifdef CONFIG_NET_STATISTICS
g_netstats.ipv6.sent++;
#endif
/* Initialize the UDP header */
ipv6udp.udp.srcport = conn->lport;
ipv6udp.udp.destport = to6->sin6_port;
ipv6udp.udp.udplen = htons(iplen);
ipv6udp.udp.udpchksum = 0;
ipv6udp.udp.udpchksum = 0;
#warning Missing logic
#if 0 /* REVISIT */
#ifdef CONFIG_NET_UDP_CHECKSUMS
/* Calculate UDP checksum. */
/* REVISIT: Current checksum logic expects the IPv6 header, the UDP header, and
* the payload data to be in contiguous memory.
*/
ipv6udp.udp.udpchksum = ~udp_ipv6_chksum(dev);
if (ipv6udp.udp.udpchksum == 0)
{
ipv6udp.udp.udpchksum = 0xffff;
}
#endif /* CONFIG_NET_UDP_CHECKSUMS */
#endif /* REVISIT */
ninfo("Outgoing UDP packet length: %d\n", iplen + IPv6_HDRLEN);
#ifdef CONFIG_NET_STATISTICS
g_netstats.udp.sent++;
#endif
/* Set the socket state to sending */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
/* Get the Rime MAC address of the destination This assumes an encoding
* of the MAC address in the IPv6 address.
*/
sixlowpan_rimefromip(to6->sin6_addr.in6_u.u6_addr16, &destmac);
/* If routable, then call sixlowpan_send() to format and send the 6loWPAN
* packet.
*/
#ifdef CONFIG_NET_SOCKOPTS
timeout = psock->s_sndtimeo;
#else
timeout = 0;
#endif
ret = sixlowpan_send(dev, (FAR const struct ipv6_hdr_s *)&ipv6udp,
buf, buflen, &destmac, timeout);
if (ret < 0)
{
nerr("ERROR: sixlowpan_send() failed: %d\n", ret);
}
/* Set the socket state to idle */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE);
return ret;
}
/****************************************************************************
* Function: psock_6lowpan_udp_send
*
* Description:
* psock_6lowpan_udp_send() call may be used with connectionlesss UDP
* sockets.
*
* Parameters:
* psock - An instance of the internal socket structure.
* buf - Data to send
* buflen - Length of data to send
*
* Returned Value:
* On success, returns the number of characters sent. On error,
* -1 is returned, and errno is set appropriately. Returned error numbers
* must be consistent with definition of errors reported by send().
*
* Assumptions:
* Called with the network locked.
*
****************************************************************************/
ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf,
size_t buflen)
{
FAR struct udp_conn_s *conn;
struct sockaddr_in6 to;
DEBUGASSERT(psock != NULL && psock->s_crefs > 0);
DEBUGASSERT(psock->s_type == SOCK_DGRAM);
@@ -114,7 +321,6 @@ ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf,
conn = (FAR struct udp_conn_s *)psock->s_conn;
DEBUGASSERT(conn != NULL);
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
/* Ignore if not IPv6 domain */
if (conn->domain != PF_INET6)
@@ -122,76 +328,16 @@ ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf,
nwarn("WARNING: Not IPv6\n");
return (ssize_t)-EPROTOTYPE;
}
#endif
/* Route outgoing message to the correct device */
/* Create the 'to' address */
#ifdef CONFIG_NETDEV_MULTINIC
dev = netdev_findby_ipv6addr(conn->u.ipv6.laddr, conn->u.ipv6.raddr);
#ifdef CONFIG_NETDEV_MULTILINK
if (dev == NULL || dev->d_lltype != NET_LL_IEEE802154)
#else
if (dev == NULL)
#endif
{
nwarn("WARNING: Not routable or not IEEE802.15.4 MAC\n");
return (ssize_t)-ENETUNREACH;
}
#else
dev = netdev_findby_ipv6addr(conn->u.ipv6.raddr);
#ifdef CONFIG_NETDEV_MULTILINK
if (dev == NULL || dev->d_lltype != NET_LL_IEEE802154)
#else
if (dev == NULL)
#endif
{
nwarn("WARNING: Not routable\n");
return (ssize_t)-ENETUNREACH;
}
#endif
to.sin6_family = AF_INET6;
to.sin6_port = conn->rport; /* Already network order */
memcpy(to.sin6_addr.in6_u.u6_addr16, conn->u.ipv6.raddr, 16);
#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
/* Make sure that the IP address mapping is in the Neighbor Table */
ret = icmpv6_neighbor(conn->u.ipv6.raddr);
if (ret < 0)
{
nerr("ERROR: Not reachable\n");
return (ssize_t)-ENETUNREACH;
}
#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);
/* Get the Rime MAC address of the destination */
#warning Missing logic
/* If routable, then call sixlowpan_send() to format and send the 6loWPAN
* packet.
*/
#ifdef CONFIG_NET_SOCKOPTS
timeout = psock->s_sndtimeo;
#else
timeout = 0;
#endif
ret = sixlowpan_send(dev, (FAR const struct ipv6_hdr_s *)&ipv6udp,
buf, len, &destmac, timeout);
if (ret < 0)
{
nerr("ERROR: sixlowpan_send() failed: %d\n", ret);
}
/* Set the socket state to idle */
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE);
return ret;
return psock_6lowpan_udp_sendto(psock, buf, buflen, 0,
(FAR const struct sockaddr *)&to,
sizeof(struct sockaddr_in6));
}
#endif /* CONFIG_NET_6LOWPAN && CONFIG_NET_UDP */
+88
View File
@@ -66,8 +66,11 @@
#include <nuttx/config.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <nuttx/net/sixlowpan.h>
#include "sixlowpan/sixlowpan_internal.h"
#ifdef CONFIG_NET_6LOWPAN
@@ -96,4 +99,89 @@ int sixlowpan_frame_hdralloc(FAR struct iob_s *iob, int size)
return -ENOMEM;
}
/****************************************************************************
* Name: sixlowpan_ipfromrime
*
* Description:
* Create a link local IPv6 address from a rime address:
*
* 128 112 96 80 64 48 32 16
* ---- ---- ---- ---- ---- ---- ---- ----
* fe80 0000 0000 0000 xxxx xxxx 0000 0000 2-byte Rime address (VALID?)
* fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte Rime address
*
****************************************************************************/
void sixlowpan_ipfromrime(FAR const struct rimeaddr_s *rime,
net_ipv6addr_t ipaddr)
{
memset(ipaddr, 0, sizeof(net_ipv6addr_t));
ipaddr[0] = 0xfe80;
/* We consider only links with IEEE EUI-64 identifier or IEEE 48-bit MAC
* addresses. NOTE: that CONFIG_NET_6LOWPAN_RIMEADDR_SIZE may be 2 or
* 8. In the case of 2, we treat the address like an 8 byte address with
* the lower bytes set to zero.
*
* REVISIT: This is just a guess so that I can continue making forward
* progress. What is the correct policy?
*/
memcpy(&ipaddr[4], rime, CONFIG_NET_6LOWPAN_RIMEADDR_SIZE);
ipaddr[4] ^= 0x0200;
}
/****************************************************************************
* Name: sixlowpan_rimefromip
*
* Description:
* Extract the rime address from a link local IPv6 address:
*
* 128 112 96 80 64 48 32 16
* ---- ---- ---- ---- ---- ---- ---- ----
* fe80 0000 0000 0000 xxxx 0000 0000 0000 2-byte Rime address (VALID?)
* fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte Rime address
*
****************************************************************************/
void sixlowpan_rimefromip(const net_ipv6addr_t ipaddr,
FAR struct rimeaddr_s *rime)
{
/* REVISIT: See notes about 2 byte addresses in sixlowpan_ipfromrime() */
DEBUGASSERT(ipaddr[0] == 0xfe80);
memcpy(rime, &ipaddr[4], CONFIG_NET_6LOWPAN_RIMEADDR_SIZE);
rime->u8[0] ^= 0x02;
}
/****************************************************************************
* Name: sixlowpan_ismacbased
*
* Description:
* Extract the rime address from a link local IPv6 address:
*
* 128 112 96 80 64 48 32 16
* ---- ---- ---- ---- ---- ---- ---- ----
* fe80 0000 0000 0000 xxxx 0000 0000 0000 2-byte Rime address (VALID?)
* fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte Rime address
*
****************************************************************************/
bool sixlowpan_ismacbased(const net_ipv6addr_t ipaddr,
FAR const struct rimeaddr_s *rime)
{
FAR const uint8_t *rimeptr = rime->u8;
#if CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 2
return ((ipaddr[4] == (GETINT16(rimeptr, 0) ^ 0x0200)) &&
ipaddr[5] == 0 && ipaddr[6] == 0 && ipaddr[7] == 0);
#else /* CONFIG_NET_6LOWPAN_RIMEADDR_SIZE == 8 */
return ((ipaddr[4] == (GETINT16(rimeptr, 0) ^ 0x0200)) &&
ipaddr[5] == GETINT16(rimeptr, 2) &&
ipaddr[6] == GETINT16(rimeptr, 4) &&
ipaddr[7] == GETINT16(rimeptr, 6));
#endif
}
#endif /* CONFIG_NET_6LOWPAN */
+11 -31
View File
@@ -1,7 +1,7 @@
/****************************************************************************
* net/socket/send.c
*
* Copyright (C) 2007-2014, 2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2014, 2016-2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -166,29 +166,18 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len,
ret = psock_6lowpan_tcp_send(psock, buf, len);
#ifdef CONFIG_NETDEV_MULTINIC
#if defined(CONFIG_NETDEV_MULTINIC) && defined(NET_TCP_HAVE_STACK)
if (ret < 0)
{
/* TCP/IP packet send */
ret = psock_tcp_send(psock, buf, len);
#ifdef NET_TCP_HAVE_STACK
ret = psock_tcp_send(psock, buf, len);
#else
ret = -ENOSYS;
#endif
}
#endif /* CONFIG_NETDEV_MULTINIC */
#else /* CONFIG_NET_6LOWPAN */
/* Only TCP/IP packet send */
#ifdef NET_TCP_HAVE_STACK
ret = psock_tcp_send(psock, buf, len);
#endif /* CONFIG_NETDEV_MULTINIC && NET_TCP_HAVE_STACK */
#elif defined(NET_TCP_HAVE_STACK)
nsent = psock_tcp_send(psock, buf, len, flags, to, tolen);
#else
ret = -ENOSYS;
#endif
nsent = -ENOSYS;
#endif /* CONFIG_NET_6LOWPAN */
}
#endif /* CONFIG_NET_TCP */
@@ -215,34 +204,25 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len,
else
#endif
{
#ifdef CONFIG_NET_6LOWPAN
#if defined(CONFIG_NET_6LOWPAN)
/* Try 6loWPAN UDP packet send */
ret = psock_6lowpan_udp_send(psock, buf, len);
#ifdef CONFIG_NETDEV_MULTINIC
#if defined(CONFIG_NETDEV_MULTINIC) && defined(NET_UDP_HAVE_STACK)
if (ret < 0)
{
/* UDP/IP packet send */
ret = psock_udp_send(psock, buf, len);
#ifdef NET_UDP_HAVE_STACK
ret = psock_udp_send(psock, buf, len);
#else
ret = -ENOSYS;
#endif
}
#endif /* CONFIG_NETDEV_MULTINIC */
#else /* CONFIG_NET_6LOWPAN */
#endif /* CONFIG_NETDEV_MULTINIC && NET_UDP_HAVE_STACK */
#elif defined(NET_UDP_HAVE_STACK)
/* Only UDP/IP packet send */
#ifdef NET_UDP_HAVE_STACK
ret = psock_udp_send(psock, buf, len);
#else
ret = -ENOSYS;
#endif
#endif /* CONFIG_NET_6LOWPAN */
}
#endif /* CONFIG_NET_UDP */
+16 -2
View File
@@ -49,6 +49,7 @@
#include <nuttx/net/net.h>
#include "udp/udp.h"
#include "sixlowpan/sixlowpan.h"
#include "local/local.h"
#include "socket/socket.h"
#include "usrsock/usrsock.h"
@@ -237,11 +238,24 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
else
#endif
{
#ifdef NET_UDP_HAVE_STACK
#if defined(CONFIG_NET_6LOWPAN)
/* Try 6loWPAN UDP packet sendto() */
nsent = psock_6lowpan_udp_sendto(psock, buf, len, flags, to, tolen);
#if defined(CONFIG_NETDEV_MULTINIC) && defined(NET_UDP_HAVE_STACK)
if (nsent < 0)
{
/* UDP/IP packet sendto */
nsent = psock_udp_sendto(psock, buf, len, flags, to, tolen);
}
#endif /* CONFIG_NETDEV_MULTINIC && NET_UDP_HAVE_STACK */
#elif defined(NET_UDP_HAVE_STACK)
nsent = psock_udp_sendto(psock, buf, len, flags, to, tolen);
#else
nsent = -ENOSYS;
#endif
#endif /* CONFIG_NET_6LOWPAN */
}
#endif /* CONFIG_NET_UDP */
+1 -1
View File
@@ -2,7 +2,7 @@
* net/tcp/tcp_input.c
* Handling incoming TCP input
*
* Copyright (C) 2007-2014 Gregory Nutt. All rights reserved.
* Copyright (C) 2007-2014, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Adapted for NuttX from logic in uIP which also has a BSD-like license: