mirror of
https://github.com/apache/nuttx.git
synced 2026-06-05 15:58:59 +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"
|
# error "Logic to support multiple Ethernet interfaces is incomplete"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If processing is not done at the interrupt level, then work queue support
|
/* Work queue support is required. */
|
||||||
* is required.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(CONFIG_SCHED_WORKQUEUE)
|
#if !defined(CONFIG_SCHED_WORKQUEUE)
|
||||||
# error Work queue support is required
|
# 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
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: net_ipv4addr_maskcmp and net_ipv6addr_maskcmp
|
* Name: net_ipv4addr_maskcmp and net_ipv6addr_maskcmp
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Compare two IP addresses under a netmask. The mask is used to mask
|
* 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
|
#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:
|
* Description:
|
||||||
* Mask out the network part of an IP address, given the address and
|
* Mask out the network part of an IP address, given the address and
|
||||||
|
|||||||
@@ -336,67 +336,51 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_NET_MULTILINK
|
#ifdef CONFIG_NET_MULTILINK
|
||||||
# undef __LAST_MIN_UDP_MSS
|
|
||||||
# undef __LAST_MAX_UDP_MSS
|
|
||||||
|
|
||||||
# ifdef CONFIG_NET_ETHERNET
|
# ifdef CONFIG_NET_ETHERNET
|
||||||
# ifdef __LAST_MIN_UDP_MSS
|
# define __MIN_UDP_MSS(h) ETH_UDP_MSS(h)
|
||||||
# define __MIN_UDP_MSS(h) MIN(ETH_UDP_MSS(h),__LAST_MIN_UDP_MSS(h))
|
# define __MAX_UDP_MSS(h) ETH_UDP_MSS(h)
|
||||||
# define __MAX_UDP_MSS(h) MAX(ETH_UDP_MSS(h),__LAST_MAX_UDP_MSS(h))
|
# define __ETH_MIN_UDP_MSS(h) ETH_UDP_MSS(h)
|
||||||
# else
|
# define __ETH_MAX_UDP_MSS(h) ETH_UDP_MSS(h)
|
||||||
# define __MIN_UDP_MSS(h) ETH_UDP_MSS(h)
|
# else
|
||||||
# define __MAX_UDP_MSS(h) ETH_UDP_MSS(h)
|
# define __ETH_MIN_UDP_MSS(h) INT_MAX
|
||||||
# endif
|
# define __ETH_MAX_UDP_MSS(h) 0
|
||||||
# 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)
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef CONFIG_NET_6LOWPAN
|
# ifdef CONFIG_NET_6LOWPAN
|
||||||
# ifdef __LAST_MIN_UDP_MSS
|
# undef __MIN_UDP_MSS
|
||||||
# define __MIN_UDP_MSS(h) MIN(IEEE802154_UDP_MSS(h),__LAST_MIN_UDP_MSS(h))
|
# undef __MIN_UDP_MSS
|
||||||
# define __MAX_UDP_MSS(h) MAX(IEEE802154_UDP_MSS(h),__LAST_MAX_UDP_MSS(h))
|
# define __MIN_UDP_MSS(h) MIN(IEEE802154_UDP_MSS(h),__ETH_MIN_UDP_MSS(h))
|
||||||
# else
|
# define __MAX_UDP_MSS(h) MAX(IEEE802154_UDP_MSS(h),__ETH_MAX_UDP_MSS(h))
|
||||||
# define __MIN_UDP_MSS(h) IEEE802154_UDP_MSS(h)
|
# define __6LOWPAN_MIN_UDP_MSS(h) MIN(IEEE802154_UDP_MSS(h),__ETH_MIN_UDP_MSS(h))
|
||||||
# define __MAX_UDP_MSS(h) IEEE802154_UDP_MSS(h)
|
# define __6LOWPAN_MAX_UDP_MSS(h) MAX(IEEE802154_UDP_MSS(h),__ETH_MAX_UDP_MSS(h))
|
||||||
# endif
|
# else
|
||||||
# undef __LAST_MIN_UDP_MSS
|
# define __6LOWPAN_MIN_UDP_MSS(h) __ETH_MIN_UDP_MSS(h)
|
||||||
# undef __LAST_MAX_UDP_MSS
|
# define __6LOWPAN_MAX_UDP_MSS(h) __ETH_MAX_UDP_MSS(h)
|
||||||
# define __LAST_MIN_UDP_MSS(h) __MIN_UDP_MSS(h)
|
|
||||||
# define __LAST_MAX_UDP_MSS(h) __MAX_UDP_MSS(h)
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef CONFIG_NET_LOOPBACK
|
# ifdef CONFIG_NET_LOOPBACK
|
||||||
# ifdef __LAST_MIN_UDP_MSS
|
# undef __MIN_UDP_MSS
|
||||||
# define __MIN_UDP_MSS(h) MIN(LO_UDP_MSS(h),__LAST_MIN_UDP_MSS(h))
|
# undef __MIN_UDP_MSS
|
||||||
# define __MAX_UDP_MSS(h) MAX(LO_UDP_MSS(h),__LAST_MAX_UDP_MSS(h))
|
# define __MIN_UDP_MSS(h) MIN(LO_UDP_MSS(h),__6LOWPAN_MIN_UDP_MSS(h))
|
||||||
# else
|
# define __MAX_UDP_MSS(h) MAX(LO_UDP_MSS(h),__6LOWPAN_MAX_UDP_MSS(h))
|
||||||
# define __MIN_UDP_MSS(h) LO_UDP_MSS(h)
|
# define __LOOP_MIN_UDP_MSS(h) MIN(LO_UDP_MSS(h),__6LOWPAN_MIN_UDP_MSS(h))
|
||||||
# define __MAX_UDP_MSS(h) LO_UDP_MSS(h)
|
# define __LOOP_MAX_UDP_MSS(h) MAX(LO_UDP_MSS(h),__6LOWPAN_MAX_UDP_MSS(h))
|
||||||
# endif
|
# else
|
||||||
# undef __LAST_MIN_UDP_MSS
|
# define __LOOP_MIN_UDP_MSS(h) __6LOWPAN_MIN_UDP_MSS(h)
|
||||||
# undef __LAST_MAX_UDP_MSS
|
# define __LOOP_MAX_UDP_MSS(h) __6LOWPAN_MAX_UDP_MSS(h)
|
||||||
# define __LAST_MIN_UDP_MSS(h) __MIN_UDP_MSS(h)
|
|
||||||
# define __LAST_MAX_UDP_MSS(h) __MAX_UDP_MSS(h)
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef CONFIG_NET_SLIP
|
# ifdef CONFIG_NET_SLIP
|
||||||
# ifdef __LAST_MIN_UDP_MSS
|
# undef __MIN_UDP_MSS
|
||||||
# define __MIN_UDP_MSS(h) MIN(SLIP_UDP_MSS(h),__LAST_MIN_UDP_MSS(h))
|
# undef __MIN_UDP_MSS
|
||||||
# define __MAX_UDP_MSS(h) MAX(SLIP_UDP_MSS(h),__LAST_MAX_UDP_MSS(h))
|
# define __MIN_UDP_MSS(h) MIN(SLIP_UDP_MSS(h),__LOOP_MIN_UDP_MSS(h))
|
||||||
# else
|
# define __MAX_UDP_MSS(h) MAX(SLIP_UDP_MSS(h),__LOOP_MAX_UDP_MSS(h))
|
||||||
# define __MIN_UDP_MSS(h) SLIP_UDP_MSS(h)
|
# define __SLIP_MIN_UDP_MSS(h) MIN(SLIP_UDP_MSS(h),__LOOP_MIN_UDP_MSS(h))
|
||||||
# define __MAX_UDP_MSS(h) SLIP_UDP_MSS(h)
|
# define __SLIP_MAX_UDP_MSS(h) MAX(SLIP_UDP_MSS(h),__LOOP_MAX_UDP_MSS(h))
|
||||||
# endif
|
# else
|
||||||
# undef __LAST_MIN_UDP_MSS
|
# define __SLIP_MIN_UDP_MSS(h) __LOOP_MIN_UDP_MSS(h)
|
||||||
# undef __LAST_MAX_UDP_MSS
|
# define __SLIP_MAX_UDP_MSS(h) __LOOP_MAX_UDP_MSS(h)
|
||||||
# define __LAST_MIN_UDP_MSS(h) __MIN_UDP_MSS(h)
|
|
||||||
# define __LAST_MAX_UDP_MSS(h) __MAX_UDP_MSS(h)
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# undef __LAST_MIN_UDP_MSS
|
|
||||||
# undef __LAST_MAX_UDP_MSS
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* NOTE: MSS calcuation excludes the UDP_HDRLEN. */
|
/* NOTE: MSS calcuation excludes the UDP_HDRLEN. */
|
||||||
@@ -531,67 +515,52 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_NET_MULTILINK
|
#ifdef CONFIG_NET_MULTILINK
|
||||||
# undef __LAST_MIN_TCP_MSS
|
|
||||||
# undef __LAST_MAX_TCP_MSS
|
|
||||||
|
|
||||||
# ifdef CONFIG_NET_ETHERNET
|
# ifdef CONFIG_NET_ETHERNET
|
||||||
# ifdef __LAST_MIN_TCP_MSS
|
# define __MIN_TCP_MSS(h) ETH_TCP_MSS(h)
|
||||||
# define __MIN_TCP_MSS(h) MIN(ETH_TCP_MSS(h),__LAST_MIN_TCP_MSS(h))
|
# define __MAX_TCP_MSS(h) ETH_TCP_MSS(h)
|
||||||
# define __MAX_TCP_MSS(h) MAX(ETH_TCP_MSS(h),__LAST_MAX_TCP_MSS(h))
|
# define __ETH_MIN_TCP_MSS(h) ETH_TCP_MSS(h)
|
||||||
# else
|
# define __ETH_MAX_TCP_MSS(h) ETH_TCP_MSS(h)
|
||||||
# define __MIN_TCP_MSS(h) ETH_TCP_MSS(h)
|
# else
|
||||||
# define __MAX_TCP_MSS(h) ETH_TCP_MSS(h)
|
# define __ETH_MIN_TCP_MSS(h) INT_MAX
|
||||||
# endif
|
# define __ETH_MAX_TCP_MSS(h) 0
|
||||||
# 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)
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef CONFIG_NET_6LOWPAN
|
# ifdef CONFIG_NET_6LOWPAN
|
||||||
# ifdef __LAST_MIN_TCP_MSS
|
# undef __MIN_TCP_MSS
|
||||||
# define __MIN_TCP_MSS(h) MIN(IEEE802154_TCP_MSS(h),__LAST_MIN_TCP_MSS(h))
|
# undef __MAX_TCP_MSS
|
||||||
# define __MAX_TCP_MSS(h) MAX(IEEE802154_TCP_MSS(h),__LAST_MAX_TCP_MSS(h))
|
# define __MIN_TCP_MSS(h) MIN(IEEE802154_TCP_MSS(h),__ETH_MIN_TCP_MSS(h))
|
||||||
# else
|
# define __MAX_TCP_MSS(h) MAX(IEEE802154_TCP_MSS(h),__ETH_MAX_TCP_MSS(h))
|
||||||
# define __MIN_TCP_MSS(h) IEEE802154_TCP_MSS(h)
|
# define __6LOWPAN_MIN_TCP_MSS(h) MIN(IEEE802154_TCP_MSS(h),__ETH_MIN_TCP_MSS(h))
|
||||||
# define __MAX_TCP_MSS(h) IEEE802154_TCP_MSS(h)
|
# define __6LOWPAN_MAX_TCP_MSS(h) MAX(IEEE802154_TCP_MSS(h),__ETH_MAX_TCP_MSS(h))
|
||||||
# endif
|
# else
|
||||||
# undef __LAST_MIN_TCP_MSS
|
# define __6LOWPAN_MIN_TCP_MSS(h) __ETH_MIN_TCP_MSS(h)
|
||||||
# undef __LAST_MAX_TCP_MSS
|
# define __6LOWPAN_MAX_TCP_MSS(h) __ETH_MAX_TCP_MSS(h)
|
||||||
# define __LAST_MIN_TCP_MSS(h) __MIN_TCP_MSS(h)
|
|
||||||
# define __LAST_MAX_TCP_MSS(h) __MAX_TCP_MSS(h)
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef CONFIG_NET_LOOPBACK
|
# ifdef CONFIG_NET_LOOPBACK
|
||||||
# ifdef __LAST_MIN_TCP_MSS
|
# undef __MIN_TCP_MSS
|
||||||
# define __MIN_TCP_MSS(h) MIN(LO_TCP_MSS(h),__LAST_MIN_TCP_MSS(h))
|
# undef __MAX_TCP_MSS
|
||||||
# define __MAX_TCP_MSS(h) MAX(LO_TCP_MSS(h),__LAST_MAX_TCP_MSS(h))
|
# define __MIN_TCP_MSS(h) MIN(LO_TCP_MSS(h),__6LOWPAN_MIN_TCP_MSS(h))
|
||||||
# else
|
# define __MAX_TCP_MSS(h) MAX(LO_TCP_MSS(h),__6LOWPAN_MAX_TCP_MSS(h))
|
||||||
# define __MIN_TCP_MSS(h) LO_TCP_MSS(h)
|
# define __LOOP_MIN_TCP_MSS(h) MIN(LO_TCP_MSS(h),__6LOWPAN_MIN_TCP_MSS(h))
|
||||||
# define __MAX_TCP_MSS(h) LO_TCP_MSS(h)
|
# define __LOOP_MAX_TCP_MSS(h) MAX(LO_TCP_MSS(h),__6LOWPAN_MAX_TCP_MSS(h))
|
||||||
# endif
|
# else
|
||||||
# undef __LAST_MIN_TCP_MSS
|
# define __LOOP_MIN_TCP_MSS(h) _6LOWPAN_MIN_TCP_MSS(h)
|
||||||
# undef __LAST_MAX_TCP_MSS
|
# define __LOOP_MAX_TCP_MSS(h) __6LOWPAN_MAX_TCP_MSS(h)
|
||||||
# define __LAST_MIN_TCP_MSS(h) __MIN_TCP_MSS(h)
|
|
||||||
# define __LAST_MAX_TCP_MSS(h) __MAX_TCP_MSS(h)
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef CONFIG_NET_SLIP
|
# ifdef CONFIG_NET_SLIP
|
||||||
# ifdef __LAST_MIN_TCP_MSS
|
# undef __MIN_TCP_MSS
|
||||||
# define __MIN_TCP_MSS(h) MIN(SLIP_TCP_MSS(h),__LAST_MIN_TCP_MSS(h))
|
# undef __MAX_TCP_MSS
|
||||||
# define __MAX_TCP_MSS(h) MAX(SLIP_TCP_MSS(h),__LAST_MAX_TCP_MSS(h))
|
# define __MIN_TCP_MSS(h) MIN(SLIP_TCP_MSS(h),__LOOP_MIN_TCP_MSS(h))
|
||||||
# else
|
# define __MAX_TCP_MSS(h) MAX(SLIP_TCP_MSS(h),__LOOP_MAX_TCP_MSS(h))
|
||||||
# define __MIN_TCP_MSS(h) SLIP_TCP_MSS(h)
|
# define __SLIP_MIN_TCP_MSS(h) MIN(SLIP_TCP_MSS(h),__LOOP_MIN_TCP_MSS(h))
|
||||||
# define __MAX_TCP_MSS(h) SLIP_TCP_MSS(h)
|
# define __SLIP_MAX_TCP_MSS(h) MAX(SLIP_TCP_MSS(h),__LOOP_MAX_TCP_MSS(h))
|
||||||
# endif
|
# else
|
||||||
# undef __LAST_MIN_TCP_MSS
|
# define __SLIP_MIN_TCP_MSS(h) __LOOP_MIN_TCP_MSS(h)
|
||||||
# undef __LAST_MAX_TCP_MSS
|
# define __SLIP_MAX_TCP_MSS(h) __LOOP_MAX_TCP_MSS(h)
|
||||||
# define __LAST_MIN_TCP_MSS(h) __MIN_TCP_MSS(h)
|
|
||||||
# define __LAST_MAX_TCP_MSS(h) __MAX_TCP_MSS(h)
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# undef __LAST_MIN_TCP_MSS
|
|
||||||
# undef __LAST_MAX_TCP_MSS
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If IPv4 is supported, it will have the larger MSS.
|
/* If IPv4 is supported, it will have the larger MSS.
|
||||||
|
|||||||
+38
-108
@@ -53,6 +53,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <nuttx/clock.h>
|
||||||
#include <nuttx/net/iob.h>
|
#include <nuttx/net/iob.h>
|
||||||
#include <nuttx/net/netdev.h>
|
#include <nuttx/net/netdev.h>
|
||||||
|
|
||||||
@@ -71,9 +72,13 @@
|
|||||||
|
|
||||||
#define SIXLOWPAN_DISPATCH_IPV6 0x41 /* 01000001 = 65 */
|
#define SIXLOWPAN_DISPATCH_IPV6 0x41 /* 01000001 = 65 */
|
||||||
#define SIXLOWPAN_DISPATCH_HC1 0x42 /* 01000010 = 66 */
|
#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_FRAG1 0xc0 /* 11000xxx */
|
||||||
#define SIXLOWPAN_DISPATCH_FRAGN 0xe0 /* 11100xxx */
|
#define SIXLOWPAN_DISPATCH_FRAGN 0xe0 /* 11100xxx */
|
||||||
|
#define SIXLOWPAN_DISPATCH_FRAG_MASK 0xf1 /* 11111000 */
|
||||||
|
|
||||||
/* HC1 encoding */
|
/* HC1 encoding */
|
||||||
|
|
||||||
@@ -155,77 +160,6 @@
|
|||||||
#define SIXLOWPAN_FRAG1_HDR_LEN 4
|
#define SIXLOWPAN_FRAG1_HDR_LEN 4
|
||||||
#define SIXLOWPAN_FRAGN_HDR_LEN 5
|
#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
|
/* This maximum size of an IEEE802.15.4 frame. Certain, non-standard
|
||||||
* devices may exceed this value, however.
|
* devices may exceed this value, however.
|
||||||
*/
|
*/
|
||||||
@@ -402,6 +336,7 @@ struct ieee802154_driver_s
|
|||||||
|
|
||||||
FAR struct iob_s *i_framelist;
|
FAR struct iob_s *i_framelist;
|
||||||
|
|
||||||
|
/* Driver Configuration ***************************************************/
|
||||||
/* i_panid. The PAN ID is 16-bit number that identifies the network. It
|
/* 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
|
* 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
|
* 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;
|
uint16_t i_dgramtag;
|
||||||
};
|
|
||||||
|
|
||||||
/* The structure of a next header compressor. This compressor is provided
|
#if CONFIG_NET_6LOWPAN_FRAG
|
||||||
* by architecture-specific logic outside of the network stack.
|
/* Fragmentation Support *************************************************/
|
||||||
*
|
/* Fragementation is handled frame by frame and requires that certain
|
||||||
* TODO: needs more parameters when compressing extension headers, etc.
|
* state information be retained from frame to frame.
|
||||||
*/
|
|
||||||
|
|
||||||
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.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CODE int (*compress)(FAR uint8_t *compressed, FAR uint8_t *uncompressed_len);
|
/* i_pktlen. The total length of the IPv6 packet to be re-assembled in
|
||||||
|
* d_buf.
|
||||||
/* Uncompress next header (TCP/UDP, etc) - ptr points to next header to
|
|
||||||
* uncompress.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CODE int (*uncompress)(FAR uint8_t *compressed, FAR uint8_t *lowpanbuf,
|
uint16_t i_pktlen;
|
||||||
FAR uint8_t *uncompressed_len);
|
|
||||||
|
/* 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);
|
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 */
|
#endif /* __INCLUDE_NUTTX_NET_SIXLOWOAN_H */
|
||||||
|
|||||||
+37
-1
@@ -95,6 +95,7 @@
|
|||||||
#include "neighbor/neighbor.h"
|
#include "neighbor/neighbor.h"
|
||||||
#include "tcp/tcp.h"
|
#include "tcp/tcp.h"
|
||||||
#include "udp/udp.h"
|
#include "udp/udp.h"
|
||||||
|
#include "sixlowpan/sixlowpan.h"
|
||||||
#include "pkt/pkt.h"
|
#include "pkt/pkt.h"
|
||||||
#include "icmpv6/icmpv6.h"
|
#include "icmpv6/icmpv6.h"
|
||||||
|
|
||||||
@@ -255,12 +256,45 @@ int ipv6_input(FAR struct net_driver_s *dev)
|
|||||||
{
|
{
|
||||||
#ifdef NET_TCP_HAVE_STACK
|
#ifdef NET_TCP_HAVE_STACK
|
||||||
case IP_PROTO_TCP: /* TCP input */
|
case IP_PROTO_TCP: /* TCP input */
|
||||||
|
/* Forward the IPv6 TCP packet */
|
||||||
|
|
||||||
tcp_ipv6_input(dev);
|
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
|
#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
|
#ifdef NET_UDP_HAVE_STACK
|
||||||
case IP_PROTO_UDP: /* UDP input */
|
case IP_PROTO_UDP: /* UDP input */
|
||||||
|
/* Forward the IPv6 UDP packet */
|
||||||
|
|
||||||
udp_ipv6_input(dev);
|
udp_ipv6_input(dev);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@@ -269,6 +303,8 @@ int ipv6_input(FAR struct net_driver_s *dev)
|
|||||||
|
|
||||||
#ifdef CONFIG_NET_ICMPv6
|
#ifdef CONFIG_NET_ICMPv6
|
||||||
case IP_PROTO_ICMP6: /* ICMP6 input */
|
case IP_PROTO_ICMP6: /* ICMP6 input */
|
||||||
|
/* Forward the ICMPv6 packet */
|
||||||
|
|
||||||
icmpv6_input(dev);
|
icmpv6_input(dev);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -132,7 +132,8 @@ config NET_6LOWPAN_MAXAGE
|
|||||||
int "Packet reassembly timeout"
|
int "Packet reassembly timeout"
|
||||||
default 20
|
default 20
|
||||||
---help---
|
---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
|
config NET_6LOWPAN_MAX_MACTRANSMITS
|
||||||
int "Max MAC transmissions"
|
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_initialize.c sixlowpan_globals.c sixlowpan_utils.c
|
||||||
NET_CSRCS += sixlowpan_input.c sixlowpan_send.c sixlowpan_framer.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)
|
ifeq ($(CONFIG_NET_TCP),y)
|
||||||
NET_CSRCS += sixlowpan_tcpsend.c
|
NET_CSRCS += sixlowpan_tcpsend.c
|
||||||
|
|||||||
@@ -53,7 +53,9 @@
|
|||||||
* Public Function Prototypes
|
* Public Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
struct socket; /* Forward reference */
|
struct net_driver_s; /* Forward reference */
|
||||||
|
struct socket; /* Forward reference */
|
||||||
|
struct sockaddr; /* Forward reference */
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: sixlowpan_initialize
|
* Name: sixlowpan_initialize
|
||||||
@@ -104,6 +106,33 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
|
|||||||
size_t len);
|
size_t len);
|
||||||
#endif
|
#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
|
* 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);
|
size_t len);
|
||||||
#endif
|
#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 /* CONFIG_NET_6LOWPAN */
|
||||||
#endif /* _NET_SIXLOWPAN_SIXLOWPAN_H */
|
#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:
|
* Input Parameters:
|
||||||
* ieee - Pointer to IEEE802.15.4 MAC driver structure.
|
* ieee - Pointer to IEEE802.15.4 MAC driver structure.
|
||||||
* ipv6 - Pointer to the IPv6 header to "compress"
|
* destip - Pointer to the IPv6 header to "compress"
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
@@ -109,7 +109,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void sixlowpan_compress_ipv6hdr(FAR struct ieee802154_driver_s *ieee,
|
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 */
|
/* 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 */
|
/* 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_rime_hdrlen += IPv6_HDRLEN;
|
||||||
g_uncomp_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,
|
int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||||
FAR const struct ipv6_hdr_s *destip,
|
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 const struct rimeaddr_s *destmac)
|
||||||
{
|
{
|
||||||
FAR struct iob_s *iob;
|
FAR struct iob_s *iob;
|
||||||
int framer_hdrlen;
|
int framer_hdrlen;
|
||||||
struct rimeaddr_s dest;
|
struct rimeaddr_s bcastmac;
|
||||||
uint16_t outlen = 0;
|
uint16_t outlen = 0;
|
||||||
|
|
||||||
/* Initialize global data. Locking the network guarantees that we have
|
/* 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)
|
if (destmac == NULL)
|
||||||
{
|
{
|
||||||
memset(&dest, 0, sizeof(struct rimeaddr_s));
|
memset(&bcastmac, 0, sizeof(struct rimeaddr_s));
|
||||||
}
|
destmac = &bcastmac;
|
||||||
else
|
|
||||||
{
|
|
||||||
rimeaddr_copy(&dest, (FAR const struct rimeaddr_s *)destmac);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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);
|
ninfo("Sending packet len %d\n", len);
|
||||||
|
|
||||||
#ifndef CONFIG_NET_6LOWPAN_COMPRESSION_IPv6
|
#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 */
|
/* Try to compress the headers */
|
||||||
|
|
||||||
#if defined(CONFIG_NET_6LOWPAN_COMPRESSION_HC1)
|
#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)
|
#elif defined(CONFIG_NET_6LOWPAN_COMPRESSION_HC06)
|
||||||
sixlowpan_compresshdr_hc06(ieee, &dest);
|
sixlowpan_compresshdr_hc06(ieee, destip, destmac, iob);
|
||||||
#else
|
#else
|
||||||
# error No compression specified
|
# error No compression specified
|
||||||
#endif
|
#endif
|
||||||
@@ -243,7 +254,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
|||||||
|
|
||||||
ninfo("Header of len %d\n", g_rime_hdrlen);
|
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. */
|
/* 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);
|
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 */
|
/* Create 1st Fragment */
|
||||||
/* Add the frame header */
|
/* Add the frame header using the pre-allocated IOB. */
|
||||||
|
|
||||||
verify = sixlowpan_framecreate(ieee, iob, ieee->i_panid);
|
verify = sixlowpan_framecreate(ieee, iob, ieee->i_panid);
|
||||||
DEBUGASSERT(verify == framer_hdrlen);
|
DEBUGASSERT(verify == framer_hdrlen);
|
||||||
@@ -434,19 +433,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
|||||||
* and send in one frame.
|
* and send in one frame.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Allocate an IOB to hold the frame, waiting if necessary. */
|
/* Add the frame header to the prealloated IOB. */
|
||||||
|
|
||||||
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 */
|
|
||||||
|
|
||||||
verify = sixlowpan_framecreate(ieee, iob, ieee->i_panid);
|
verify = sixlowpan_framecreate(ieee, iob, ieee->i_panid);
|
||||||
DEBUGASSERT(vreify == framer_hdrlen);
|
DEBUGASSERT(vreify == framer_hdrlen);
|
||||||
|
|||||||
@@ -47,10 +47,6 @@
|
|||||||
* Public Data
|
* 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
|
/* The following data values are used to hold intermediate settings while
|
||||||
* processing IEEE802.15.4 frames. These globals are shared with incoming
|
* processing IEEE802.15.4 frames. These globals are shared with incoming
|
||||||
* and outgoing frame processing and possibly with mutliple IEEE802.15.4 MAC
|
* 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
|
#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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -102,9 +113,11 @@
|
|||||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
*
|
*
|
||||||
* Input Parmeters:
|
* Input Parmeters:
|
||||||
* ieee - A reference to the IEE802.15.4 network device state
|
* ieee - A reference to the IEE802.15.4 network device state
|
||||||
* destaddr - L2 destination address, needed to compress the IP
|
* ipv6 - The IPv6 header to be compressed
|
||||||
* destination field
|
* destmac - L2 destination address, needed to compress the IP
|
||||||
|
* destination field
|
||||||
|
* iob - The IOB into which the compressed header should be saved.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
@@ -112,9 +125,109 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
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.
|
* fragment.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* 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,
|
int sixlowpan_uncompresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
||||||
uint16_t iplen)
|
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 */
|
#endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC1 */
|
||||||
|
|||||||
+415
-92
File diff suppressed because it is too large
Load Diff
@@ -225,10 +225,72 @@
|
|||||||
#define FRAME_SIZE(ieee,iob) \
|
#define FRAME_SIZE(ieee,iob) \
|
||||||
((iob)->io_len)
|
((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 ****************************************************/
|
/* General helper macros ****************************************************/
|
||||||
|
|
||||||
#define GETINT16(ptr,index) \
|
#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) \
|
#define PUTINT16(ptr,index,value) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
@@ -335,11 +397,6 @@ struct frame802154_s
|
|||||||
* Public Data
|
* 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
|
/* The following data values are used to hold intermediate settings while
|
||||||
* processing IEEE802.15.4 frames. These globals are shared with incoming
|
* processing IEEE802.15.4 frames. These globals are shared with incoming
|
||||||
* and outgoing frame processing and possibly with mutliple IEEE802.15.4 MAC
|
* 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 net_driver_s; /* Forward reference */
|
||||||
struct ieee802154_driver_s; /* Forward reference */
|
struct ieee802154_driver_s; /* Forward reference */
|
||||||
|
struct ipv6_hdr_s; /* Forward reference */
|
||||||
struct rimeaddr_s; /* Forward reference */
|
struct rimeaddr_s; /* Forward reference */
|
||||||
struct iob_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
|
* it to be sent on an 802.15.4 network using 6lowpan. Called from common
|
||||||
* UDP/TCP send logic.
|
* 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
|
* Compressed headers will be added and if necessary the packet is
|
||||||
* fragmented. The resulting packet/fragments are put in ieee->i_framelist
|
* 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
|
* 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:
|
* Input Parameters:
|
||||||
* dev - The IEEE802.15.4 MAC network driver interface.
|
* 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
|
* buf - Data to send
|
||||||
* len - Length of data to send
|
* buflen - Length of data to send
|
||||||
* raddr - The MAC address of the destination
|
* raddr - The MAC address of the destination
|
||||||
* timeout - Send timeout in deciseconds
|
* timeout - Send timeout in deciseconds
|
||||||
*
|
*
|
||||||
@@ -433,8 +491,8 @@ struct iob_s; /* Forward reference */
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int sixlowpan_send(FAR struct net_driver_s *dev,
|
int sixlowpan_send(FAR struct net_driver_s *dev,
|
||||||
FAR const struct ipv6_hdr_s *ipv6, FAR const void *buf,
|
FAR const struct ipv6_hdr_s *destip, FAR const void *buf,
|
||||||
size_t len, FAR const struct rimeaddr_s *raddr,
|
size_t buflen, FAR const struct rimeaddr_s *raddr,
|
||||||
uint16_t timeout);
|
uint16_t timeout);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -499,7 +557,7 @@ int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee,
|
|||||||
* ieee - The IEEE802.15.4 MAC driver instance
|
* ieee - The IEEE802.15.4 MAC driver instance
|
||||||
* ipv6hdr - IPv6 header followed by TCP or UDP header.
|
* ipv6hdr - IPv6 header followed by TCP or UDP header.
|
||||||
* buf - Data to send
|
* 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
|
* destmac - The IEEE802.15.4 MAC address of the destination
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* 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,
|
int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
|
||||||
FAR const struct ipv6_hdr_s *ipv6hdr,
|
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);
|
FAR const struct rimeaddr_s *destmac);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -542,7 +600,7 @@ void sixlowpan_hc06_initialize(void);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: sixlowpan_hc06_initialize
|
* Name: sixlowpan_compresshdr_hc06
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Compress IP/UDP header
|
* Compress IP/UDP header
|
||||||
@@ -559,7 +617,10 @@ void sixlowpan_hc06_initialize(void);
|
|||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* ieee - A reference to the IEE802.15.4 network device state
|
* 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:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
@@ -567,12 +628,14 @@ void sixlowpan_hc06_initialize(void);
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
|
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
|
||||||
void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *dev,
|
void sixlowpan_compresshdr_hc06(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
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: sixlowpan_hc06_initialize
|
* Name: sixlowpan_uncompresshdr_hc06
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Uncompress HC06 (i.e., IPHC and LOWPAN_UDP) headers and put them in
|
* 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:
|
* Input Parmeters:
|
||||||
* ieee - A reference to the IEE802.15.4 network device state
|
* 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
|
* 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.
|
* fragment.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
@@ -611,9 +674,11 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
|
|||||||
* uip_buf buffer.
|
* uip_buf buffer.
|
||||||
*
|
*
|
||||||
* Input Parmeters:
|
* Input Parmeters:
|
||||||
* ieee - A reference to the IEE802.15.4 network device state
|
* ieee - A reference to the IEE802.15.4 network device state
|
||||||
* destaddr - L2 destination address, needed to compress the IP
|
* ipv6 - The IPv6 header to be compressed
|
||||||
* destination field
|
* destmac - L2 destination address, needed to compress the IP
|
||||||
|
* destination field
|
||||||
|
* iob - The IOB into which the compressed header should be saved.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
@@ -622,7 +687,9 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
|
|||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1
|
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1
|
||||||
void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
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
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -640,7 +707,7 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
|
|||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* ieee - A reference to the IEE802.15.4 network device state
|
* 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
|
* 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.
|
* fragment.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* 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);
|
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 /* CONFIG_NET_6LOWPAN */
|
||||||
#endif /* _NET_SIXLOWPAN_SIXLOWPAN_INTERNAL_H */
|
#endif /* _NET_SIXLOWPAN_SIXLOWPAN_INTERNAL_H */
|
||||||
|
|||||||
@@ -54,6 +54,17 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN
|
#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
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -172,6 +183,7 @@ static uint16_t send_interrupt(FAR struct net_driver_s *dev,
|
|||||||
sinfo->s_destmac);
|
sinfo->s_destmac);
|
||||||
|
|
||||||
flags &= ~WPAN_POLL;
|
flags &= ~WPAN_POLL;
|
||||||
|
neighbor_reachable(dev);
|
||||||
goto end_wait;
|
goto end_wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,6 +195,7 @@ static uint16_t send_interrupt(FAR struct net_driver_s *dev,
|
|||||||
|
|
||||||
nwarn("WARNING: SEND timeout\n");
|
nwarn("WARNING: SEND timeout\n");
|
||||||
sinfo->s_result = -ETIMEDOUT;
|
sinfo->s_result = -ETIMEDOUT;
|
||||||
|
neighbor_notreachable(dev);
|
||||||
goto end_wait;
|
goto end_wait;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,11 +39,13 @@
|
|||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
#include "nuttx/net/netdev.h"
|
#include "nuttx/net/netdev.h"
|
||||||
|
#include "nuttx/net/netstats.h"
|
||||||
|
|
||||||
#include "netdev/netdev.h"
|
#include "netdev/netdev.h"
|
||||||
#include "socket/socket.h"
|
#include "socket/socket.h"
|
||||||
@@ -66,7 +68,7 @@
|
|||||||
* Parameters:
|
* Parameters:
|
||||||
* psock - An instance of the internal socket structure.
|
* psock - An instance of the internal socket structure.
|
||||||
* buf - Data to send
|
* buf - Data to send
|
||||||
* len - Length of data to send
|
* bulen - Length of data to send
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* On success, returns the number of characters sent. On error,
|
* 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,
|
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 tcp_conn_s *conn;
|
||||||
FAR struct net_driver_s *dev;
|
FAR struct net_driver_s *dev;
|
||||||
struct ipv6tcp_hdr_s ipv6tcp;
|
struct ipv6tcp_hdr_s ipv6tcp;
|
||||||
struct rimeaddr_s destmac;
|
struct rimeaddr_s destmac;
|
||||||
uint16_t timeout;
|
uint16_t timeout;
|
||||||
|
uint16_t iplen;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
DEBUGASSERT(psock != NULL && psock->s_crefs > 0);
|
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;
|
conn = (FAR struct tcp_conn_s *)psock->s_conn;
|
||||||
DEBUGASSERT(conn != NULL);
|
DEBUGASSERT(conn != NULL);
|
||||||
|
|
||||||
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
#ifdef CONFIG_NET_IPv4
|
||||||
/* Ignore if not IPv6 domain */
|
/* Ignore if not IPv6 domain */
|
||||||
|
|
||||||
if (conn->domain != PF_INET6)
|
if (conn->domain != PF_INET6)
|
||||||
@@ -161,14 +164,88 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Initialize the IPv6/TCP headers */
|
/* 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 */
|
/* Set the socket state to sending */
|
||||||
|
|
||||||
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
|
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
|
||||||
|
|
||||||
/* Get the Rime MAC address of the destination */
|
/* Get the Rime MAC address of the destination This assumes an encoding
|
||||||
#warning Missing logic
|
* 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
|
/* If routable, then call sixlowpan_send() to format and send the 6loWPAN
|
||||||
* packet.
|
* packet.
|
||||||
@@ -181,7 +258,7 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = sixlowpan_send(dev, (FAR const struct ipv6_hdr_s *)&ipv6tcp,
|
ret = sixlowpan_send(dev, (FAR const struct ipv6_hdr_s *)&ipv6tcp,
|
||||||
buf, len, &destmac, timeout);
|
buf, buflen, &destmac, timeout);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nerr("ERROR: sixlowpan_send() failed: %d\n", ret);
|
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;
|
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 */
|
#endif /* CONFIG_NET_6LOWPAN && CONFIG_NET_TCP */
|
||||||
|
|||||||
@@ -39,11 +39,14 @@
|
|||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
#include "nuttx/net/netdev.h"
|
#include "nuttx/net/netdev.h"
|
||||||
|
#include "nuttx/net/netstats.h"
|
||||||
|
|
||||||
#include "netdev/netdev.h"
|
#include "netdev/netdev.h"
|
||||||
#include "socket/socket.h"
|
#include "socket/socket.h"
|
||||||
@@ -57,21 +60,26 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: psock_6lowpan_udp_send
|
* Function: psock_6lowpan_udp_sendto
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* psock_6lowpan_udp_send() call may be used with connectionlesss UDP
|
* If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET)
|
||||||
* sockets.
|
* 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:
|
* Parameters:
|
||||||
* psock - An instance of the internal socket structure.
|
* psock A pointer to a NuttX-specific, internal socket structure
|
||||||
* buf - Data to send
|
* buf Data to send
|
||||||
* len - Length of 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:
|
* Returned Value:
|
||||||
* On success, returns the number of characters sent. On error,
|
* On success, returns the number of characters sent. On error,
|
||||||
* -1 is returned, and errno is set appropriately. Returned error numbers
|
* -1 is returned, and errno is set appropriately. Returned error
|
||||||
* must be consistent with definition of errors reported by send() or
|
* number must be consistent with definition of errors reported by
|
||||||
* sendto().
|
* sendto().
|
||||||
*
|
*
|
||||||
* Assumptions:
|
* Assumptions:
|
||||||
@@ -79,16 +87,215 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
ssize_t psock_6lowpan_udp_send(FAR struct socket *psock, FAR const void *buf,
|
ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock,
|
||||||
size_t len)
|
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 udp_conn_s *conn;
|
||||||
FAR struct net_driver_s *dev;
|
FAR struct net_driver_s *dev;
|
||||||
struct ipv6udp_hdr_s ipv6udp;
|
struct ipv6udp_hdr_s ipv6udp;
|
||||||
struct rimeaddr_s destmac;
|
struct rimeaddr_s destmac;
|
||||||
|
uint16_t iplen;
|
||||||
uint16_t timeout;
|
uint16_t timeout;
|
||||||
int ret;
|
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 != NULL && psock->s_crefs > 0);
|
||||||
DEBUGASSERT(psock->s_type == SOCK_DGRAM);
|
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;
|
conn = (FAR struct udp_conn_s *)psock->s_conn;
|
||||||
DEBUGASSERT(conn != NULL);
|
DEBUGASSERT(conn != NULL);
|
||||||
|
|
||||||
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
|
||||||
/* Ignore if not IPv6 domain */
|
/* Ignore if not IPv6 domain */
|
||||||
|
|
||||||
if (conn->domain != PF_INET6)
|
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");
|
nwarn("WARNING: Not IPv6\n");
|
||||||
return (ssize_t)-EPROTOTYPE;
|
return (ssize_t)-EPROTOTYPE;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Route outgoing message to the correct device */
|
/* Create the 'to' address */
|
||||||
|
|
||||||
#ifdef CONFIG_NETDEV_MULTINIC
|
to.sin6_family = AF_INET6;
|
||||||
dev = netdev_findby_ipv6addr(conn->u.ipv6.laddr, conn->u.ipv6.raddr);
|
to.sin6_port = conn->rport; /* Already network order */
|
||||||
#ifdef CONFIG_NETDEV_MULTILINK
|
memcpy(to.sin6_addr.in6_u.u6_addr16, conn->u.ipv6.raddr, 16);
|
||||||
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
|
|
||||||
|
|
||||||
#ifdef CONFIG_NET_ICMPv6_NEIGHBOR
|
return psock_6lowpan_udp_sendto(psock, buf, buflen, 0,
|
||||||
/* Make sure that the IP address mapping is in the Neighbor Table */
|
(FAR const struct sockaddr *)&to,
|
||||||
|
sizeof(struct sockaddr_in6));
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_NET_6LOWPAN && CONFIG_NET_UDP */
|
#endif /* CONFIG_NET_6LOWPAN && CONFIG_NET_UDP */
|
||||||
|
|||||||
@@ -66,8 +66,11 @@
|
|||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <nuttx/net/sixlowpan.h>
|
||||||
|
|
||||||
#include "sixlowpan/sixlowpan_internal.h"
|
#include "sixlowpan/sixlowpan_internal.h"
|
||||||
|
|
||||||
#ifdef CONFIG_NET_6LOWPAN
|
#ifdef CONFIG_NET_6LOWPAN
|
||||||
@@ -96,4 +99,89 @@ int sixlowpan_frame_hdralloc(FAR struct iob_s *iob, int size)
|
|||||||
return -ENOMEM;
|
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 */
|
#endif /* CONFIG_NET_6LOWPAN */
|
||||||
|
|||||||
+10
-30
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/socket/send.c
|
* 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>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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);
|
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)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
/* TCP/IP packet send */
|
/* TCP/IP packet send */
|
||||||
|
|
||||||
ret = psock_tcp_send(psock, buf, len);
|
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 && NET_TCP_HAVE_STACK */
|
||||||
#endif /* CONFIG_NETDEV_MULTINIC */
|
#elif defined(NET_TCP_HAVE_STACK)
|
||||||
#else /* CONFIG_NET_6LOWPAN */
|
nsent = psock_tcp_send(psock, buf, len, flags, to, tolen);
|
||||||
|
|
||||||
/* Only TCP/IP packet send */
|
|
||||||
|
|
||||||
#ifdef NET_TCP_HAVE_STACK
|
|
||||||
ret = psock_tcp_send(psock, buf, len);
|
|
||||||
#else
|
#else
|
||||||
ret = -ENOSYS;
|
nsent = -ENOSYS;
|
||||||
#endif
|
|
||||||
#endif /* CONFIG_NET_6LOWPAN */
|
#endif /* CONFIG_NET_6LOWPAN */
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_TCP */
|
#endif /* CONFIG_NET_TCP */
|
||||||
@@ -215,34 +204,25 @@ ssize_t psock_send(FAR struct socket *psock, FAR const void *buf, size_t len,
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_NET_6LOWPAN
|
#if defined(CONFIG_NET_6LOWPAN)
|
||||||
/* Try 6loWPAN UDP packet send */
|
/* Try 6loWPAN UDP packet send */
|
||||||
|
|
||||||
ret = psock_6lowpan_udp_send(psock, buf, len);
|
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)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
/* UDP/IP packet send */
|
/* UDP/IP packet send */
|
||||||
|
|
||||||
ret = psock_udp_send(psock, buf, len);
|
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 && NET_UDP_HAVE_STACK */
|
||||||
#endif /* CONFIG_NETDEV_MULTINIC */
|
#elif defined(NET_UDP_HAVE_STACK)
|
||||||
#else /* CONFIG_NET_6LOWPAN */
|
|
||||||
|
|
||||||
/* Only UDP/IP packet send */
|
/* Only UDP/IP packet send */
|
||||||
|
|
||||||
#ifdef NET_UDP_HAVE_STACK
|
|
||||||
ret = psock_udp_send(psock, buf, len);
|
ret = psock_udp_send(psock, buf, len);
|
||||||
#else
|
#else
|
||||||
ret = -ENOSYS;
|
ret = -ENOSYS;
|
||||||
#endif
|
|
||||||
#endif /* CONFIG_NET_6LOWPAN */
|
#endif /* CONFIG_NET_6LOWPAN */
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_UDP */
|
#endif /* CONFIG_NET_UDP */
|
||||||
|
|||||||
+16
-2
@@ -49,6 +49,7 @@
|
|||||||
#include <nuttx/net/net.h>
|
#include <nuttx/net/net.h>
|
||||||
|
|
||||||
#include "udp/udp.h"
|
#include "udp/udp.h"
|
||||||
|
#include "sixlowpan/sixlowpan.h"
|
||||||
#include "local/local.h"
|
#include "local/local.h"
|
||||||
#include "socket/socket.h"
|
#include "socket/socket.h"
|
||||||
#include "usrsock/usrsock.h"
|
#include "usrsock/usrsock.h"
|
||||||
@@ -237,11 +238,24 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
|
|||||||
else
|
else
|
||||||
#endif
|
#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);
|
nsent = psock_udp_sendto(psock, buf, len, flags, to, tolen);
|
||||||
#else
|
#else
|
||||||
nsent = -ENOSYS;
|
nsent = -ENOSYS;
|
||||||
#endif
|
#endif /* CONFIG_NET_6LOWPAN */
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_UDP */
|
#endif /* CONFIG_NET_UDP */
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
* net/tcp/tcp_input.c
|
* net/tcp/tcp_input.c
|
||||||
* Handling incoming TCP input
|
* 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>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Adapted for NuttX from logic in uIP which also has a BSD-like license:
|
* Adapted for NuttX from logic in uIP which also has a BSD-like license:
|
||||||
|
|||||||
Reference in New Issue
Block a user