6loWPAN: Hook 6loWPAN output into path of output from TCP state machine.
This commit is contained in:
parent
76406af71b
commit
663c48c329
@ -95,6 +95,7 @@
|
||||
#include "neighbor/neighbor.h"
|
||||
#include "tcp/tcp.h"
|
||||
#include "udp/udp.h"
|
||||
#include "sixlowpan/sixlowpan.h"
|
||||
#include "pkt/pkt.h"
|
||||
#include "icmpv6/icmpv6.h"
|
||||
|
||||
|
@ -53,8 +53,9 @@
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
struct socket; /* Forward reference */
|
||||
struct sockaddr; /* Forward reference */
|
||||
struct net_driver_s; /* Forward reference */
|
||||
struct socket; /* Forward reference */
|
||||
struct sockaddr; /* Forward reference */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sixlowpan_initialize
|
||||
@ -105,6 +106,33 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
|
||||
size_t len);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sixlowpan_tcp_send
|
||||
*
|
||||
* Description:
|
||||
* TCP output comes through two different mechansims. Either from:
|
||||
*
|
||||
* 1. TCP socket output. For the case of TCP output to an
|
||||
* IEEE802.15.4, the TCP output is caught in the socket
|
||||
* send()/sendto() logic and and redirected to psock_6lowpan_tcp_send().
|
||||
* 2. TCP output from the TCP state machine. That will occur
|
||||
* during TCP packet processing by the TCP state meachine. It
|
||||
* is detected there when ipv6_tcp_input() returns with d_len > 0. This
|
||||
* will be redirected here.
|
||||
*
|
||||
* Parameters:
|
||||
* dev - An instance of nework device state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called with the network locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void sixlowpan_tcp_send(FAR struct net_driver_s *dev);
|
||||
|
||||
/****************************************************************************
|
||||
* Function: psock_6lowpan_udp_send
|
||||
*
|
||||
|
@ -91,91 +91,6 @@
|
||||
* 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
|
||||
*
|
||||
@ -691,7 +606,10 @@ int sixlowpan_input(FAR struct ieee802154_driver_s *ieee)
|
||||
if (ieee->i_dev.d_len > 0)
|
||||
{
|
||||
FAR struct ipv6_hdr_s *ipv6hdr;
|
||||
FAR uint8_t *buffer;
|
||||
struct rimeaddr_s destmac;
|
||||
size_t hdrlen;
|
||||
size_t buflen;
|
||||
|
||||
/* The IPv6 header followed by TCP or UDP headers should
|
||||
* 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);
|
||||
|
||||
/* 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. */
|
||||
|
||||
ret = sixlowpan_queue_frames(ieee, ipv6hdr, ieee->i_dev.d_buf,
|
||||
ieee->i_dev.d_len, &destmac);
|
||||
buffer = ieee->i_dev.d_buf + hdrlen;
|
||||
buflen = ieee->i_dev.d_len - hdrlen;
|
||||
|
||||
ret = sixlowpan_queue_frames(ieee, ipv6hdr, buffer, buflen,
|
||||
&destmac);
|
||||
drop:
|
||||
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;
|
||||
DEBUGASSERT(conn != NULL);
|
||||
|
||||
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
/* Ignore if not IPv6 domain */
|
||||
|
||||
if (conn->domain != PF_INET6)
|
||||
@ -196,4 +196,86 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Function: sixlowpan_tcp_send
|
||||
*
|
||||
* Description:
|
||||
* TCP output comes through two different mechansims. Either from:
|
||||
*
|
||||
* 1. TCP socket output. For the case of TCP output to an
|
||||
* IEEE802.15.4, the TCP output is caught in the socket
|
||||
* send()/sendto() logic and and redirected to psock_6lowpan_tcp_send().
|
||||
* 2. TCP output from the TCP state machine. That will occur
|
||||
* during TCP packet processing by the TCP state meachine. It
|
||||
* is detected there when ipv6_tcp_input() returns with d_len > 0. This
|
||||
* will be redirected here.
|
||||
*
|
||||
* Parameters:
|
||||
* dev - An instance of nework device state structure
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
* Assumptions:
|
||||
* Called with the network locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void sixlowpan_tcp_send(FAR struct net_driver_s *dev)
|
||||
{
|
||||
DEBUGASSERT(dev != NULL && dev->d_len > 0);
|
||||
|
||||
/* Double check */
|
||||
|
||||
if (dev != NULL && dev->d_len > 0)
|
||||
{
|
||||
FAR struct ipv6_hdr_s *ipv6hdr;
|
||||
|
||||
/* The IPv6 header followed by a TCP headers should lie at the
|
||||
* beginning of d_buf since there is no link layer protocol header
|
||||
* and the TCP state machine should only response with TCP packets.
|
||||
*/
|
||||
|
||||
ipv6hdr = (FAR struct ipv6_hdr_s *)(dev->d_buf);
|
||||
|
||||
/* The TCP data payload should follow the IPv6 header plus the
|
||||
* protocol header.
|
||||
*/
|
||||
|
||||
if (ipv6hdr->proto != IP_PROTO_TCP)
|
||||
{
|
||||
nwarn("WARNING: Expected TCP protoype: %u\n", ipv6hdr->proto);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t hdrlen;
|
||||
|
||||
hdrlen = IPv6_HDRLEN + TCP_HDRLEN;
|
||||
if (hdrlen < dev->d_len)
|
||||
{
|
||||
nwarn("WARNING: Packet to small: Have %u need >%u\n",
|
||||
dev->d_len, hdrlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct rimeaddr_s destmac;
|
||||
|
||||
/* Get the Rime MAC address of the destination. This assumes
|
||||
* an encoding of the MAC address in the IPv6 address.
|
||||
*/
|
||||
|
||||
sixlowpan_rimefromip(ipv6hdr->destipaddr, &destmac);
|
||||
|
||||
/* Convert the outgoing packet into a frame list. */
|
||||
|
||||
(void)sixlowpan_queue_frames(
|
||||
(FAR struct ieee802154_driver_s *)dev, ipv6hdr,
|
||||
dev->d_buf + hdrlen, dev->d_len - hdrlen, &destmac);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dev->d_len = 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NET_6LOWPAN && CONFIG_NET_TCP */
|
||||
|
Loading…
x
Reference in New Issue
Block a user