mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 00:14:22 +08:00
Merge remote-tracking branch 'origin/master' into ieee802154
This commit is contained in:
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
+946
-13
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
|
||||
+415
-92
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user