mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 20:08:15 +08:00
6loWPAN: Hook 6loWPAN output into path of output from TCP state machine.
This commit is contained in:
@@ -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"
|
||||||
|
|
||||||
|
|||||||
@@ -53,8 +53,9 @@
|
|||||||
* Public Function Prototypes
|
* Public Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
struct socket; /* Forward reference */
|
struct net_driver_s; /* Forward reference */
|
||||||
struct sockaddr; /* Forward reference */
|
struct socket; /* Forward reference */
|
||||||
|
struct sockaddr; /* Forward reference */
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: sixlowpan_initialize
|
* Name: sixlowpan_initialize
|
||||||
@@ -105,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
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -91,91 +91,6 @@
|
|||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Function: sixlowpan_isbroadcast
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Return the address length associated with a 2-bit address mode
|
|
||||||
*
|
|
||||||
* Input parameters:
|
|
||||||
* addrmode - The address mode
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* The address length associated with the address mode.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static bool sixlowpan_isbroadcast(uint8_t mode, FAR uint8_t *addr)
|
|
||||||
{
|
|
||||||
int i = ((mode == FRAME802154_SHORTADDRMODE) ? 2 : 8);
|
|
||||||
|
|
||||||
while (i-- > 0)
|
|
||||||
{
|
|
||||||
if (addr[i] != 0xff)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: sixlowpan_set_pktattrs
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Setup some packet buffer attributes
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* ieee - Pointer to IEEE802.15.4 MAC driver structure.
|
|
||||||
* ipv6 - Pointer to the IPv6 header to "compress"
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static void sixlowpan_set_pktattrs(FAR struct ieee802154_driver_s *ieee,
|
|
||||||
FAR const struct ipv6_hdr_s *ipv6)
|
|
||||||
{
|
|
||||||
int attr = 0;
|
|
||||||
|
|
||||||
/* Set protocol in NETWORK_ID */
|
|
||||||
|
|
||||||
g_pktattrs[PACKETBUF_ATTR_NETWORK_ID] = ipv6->proto;
|
|
||||||
|
|
||||||
/* Assign values to the channel attribute (port or type + code) */
|
|
||||||
|
|
||||||
if (ipv6->proto == IP_PROTO_UDP)
|
|
||||||
{
|
|
||||||
FAR struct udp_hdr_s *udp = &((FAR struct ipv6udp_hdr_s *)ipv6)->udp;
|
|
||||||
|
|
||||||
attr = udp->srcport;
|
|
||||||
if (udp->destport < attr)
|
|
||||||
{
|
|
||||||
attr = udp->destport;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (ipv6->proto == IP_PROTO_TCP)
|
|
||||||
{
|
|
||||||
FAR struct tcp_hdr_s *tcp = &((FAR struct ipv6tcp_hdr_s *)ipv6)->tcp;
|
|
||||||
|
|
||||||
attr = tcp->srcport;
|
|
||||||
if (tcp->destport < attr)
|
|
||||||
{
|
|
||||||
attr = tcp->destport;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (ipv6->proto == IP_PROTO_ICMP6)
|
|
||||||
{
|
|
||||||
FAR struct icmpv6_iphdr_s *icmp = &((FAR struct ipv6icmp_hdr_s *)ipv6)->icmp;
|
|
||||||
|
|
||||||
attr = icmp->type << 8 | icmp->code;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_pktattrs[PACKETBUF_ATTR_CHANNEL] = attr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: sixlowpan_frame_process
|
* Name: sixlowpan_frame_process
|
||||||
*
|
*
|
||||||
@@ -691,7 +606,10 @@ int sixlowpan_input(FAR struct ieee802154_driver_s *ieee)
|
|||||||
if (ieee->i_dev.d_len > 0)
|
if (ieee->i_dev.d_len > 0)
|
||||||
{
|
{
|
||||||
FAR struct ipv6_hdr_s *ipv6hdr;
|
FAR struct ipv6_hdr_s *ipv6hdr;
|
||||||
|
FAR uint8_t *buffer;
|
||||||
struct rimeaddr_s destmac;
|
struct rimeaddr_s destmac;
|
||||||
|
size_t hdrlen;
|
||||||
|
size_t buflen;
|
||||||
|
|
||||||
/* The IPv6 header followed by TCP or UDP headers should
|
/* The IPv6 header followed by TCP or UDP headers should
|
||||||
* lie at the beginning of d_buf since there is no link
|
* lie at the beginning of d_buf since there is no link
|
||||||
@@ -707,10 +625,46 @@ int sixlowpan_input(FAR struct ieee802154_driver_s *ieee)
|
|||||||
|
|
||||||
sixlowpan_rimefromip(ipv6hdr->destipaddr, &destmac);
|
sixlowpan_rimefromip(ipv6hdr->destipaddr, &destmac);
|
||||||
|
|
||||||
|
/* The data payload should follow the IPv6 header plus
|
||||||
|
* the protocol header.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ipv6hdr->proto != IP_PROTO_TCP)
|
||||||
|
{
|
||||||
|
hdrlen = IPv6_HDRLEN + TCP_HDRLEN;
|
||||||
|
}
|
||||||
|
else if (ipv6hdr->proto != IP_PROTO_UDP)
|
||||||
|
{
|
||||||
|
hdrlen = IPv6_HDRLEN + UDP_HDRLEN;
|
||||||
|
}
|
||||||
|
else if (ipv6hdr->proto != IP_PROTO_ICMP6)
|
||||||
|
{
|
||||||
|
hdrlen = IPv6_HDRLEN + ICMPv6_HDRLEN;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nwarn("WARNING: Unsupported protoype: %u\n",
|
||||||
|
ipv6hdr->proto);
|
||||||
|
ret = -EPROTO;
|
||||||
|
goto drop;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hdrlen < ieee->i_dev.d_len)
|
||||||
|
{
|
||||||
|
nwarn("WARNING: Packet to small: Have %u need >%u\n",
|
||||||
|
ieee->i_dev.d_len, hdrlen);
|
||||||
|
ret = -ENOBUFS;
|
||||||
|
goto drop;
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert the outgoing packet into a frame list. */
|
/* Convert the outgoing packet into a frame list. */
|
||||||
|
|
||||||
ret = sixlowpan_queue_frames(ieee, ipv6hdr, ieee->i_dev.d_buf,
|
buffer = ieee->i_dev.d_buf + hdrlen;
|
||||||
ieee->i_dev.d_len, &destmac);
|
buflen = ieee->i_dev.d_len - hdrlen;
|
||||||
|
|
||||||
|
ret = sixlowpan_queue_frames(ieee, ipv6hdr, buffer, buflen,
|
||||||
|
&destmac);
|
||||||
|
drop:
|
||||||
ieee->i_dev.d_len = 0;
|
ieee->i_dev.d_len = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,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)
|
||||||
@@ -196,4 +196,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 */
|
||||||
|
|||||||
Reference in New Issue
Block a user