6LoWPAN: Modify the the way TCP headers are transferred -- yet again. TCP packet reassembly now seems to work OK, but no there now does not seem to be a listener on the port.

This commit is contained in:
Gregory Nutt 2017-06-24 21:12:46 -06:00
parent 73d32a962d
commit 58e3558c55
5 changed files with 163 additions and 155 deletions

View file

@ -125,8 +125,6 @@
static void sixlowpan_compress_ipv6hdr(FAR const struct ipv6_hdr_s *ipv6hdr,
FAR uint8_t *fptr)
{
uint16_t protosize;
/* Indicate the IPv6 dispatch and length */
fptr[g_frame_hdrlen] = SIXLOWPAN_DISPATCH_IPV6;
@ -137,7 +135,28 @@ static void sixlowpan_compress_ipv6hdr(FAR const struct ipv6_hdr_s *ipv6hdr,
memcpy(&fptr[g_frame_hdrlen], ipv6hdr, IPv6_HDRLEN);
g_frame_hdrlen += IPv6_HDRLEN;
g_uncomp_hdrlen += IPv6_HDRLEN;
}
/****************************************************************************
* Name: sixlowpan_protosize
*
* Description:
* Get the size of any uncompresssed protocol header that follows the
* IPv6 header.
*
****************************************************************************/
static uint16_t sixlowpan_protosize(FAR const struct ipv6_hdr_s *ipv6hdr,
FAR uint8_t *fptr)
{
uint16_t protosize;
/* Do we already have an encoded protocol header? If not, it needs to
* coped as raw data in the fist packet of a fragement.
*/
if (!g_have_protohdr)
{
/* Copy the following protocol header, */
switch (ipv6hdr->proto)
@ -145,7 +164,8 @@ static void sixlowpan_compress_ipv6hdr(FAR const struct ipv6_hdr_s *ipv6hdr,
#ifdef CONFIG_NET_TCP
case IP_PROTO_TCP:
{
FAR struct tcp_hdr_s *tcp = &((FAR struct ipv6tcp_hdr_s *)ipv6hdr)->tcp;
FAR struct tcp_hdr_s *tcp =
&((FAR struct ipv6tcp_hdr_s *)ipv6hdr)->tcp;
/* The TCP header length is encoded in the top 4 bits of the
* tcpoffset field (in units of 32-bit words).
@ -158,28 +178,23 @@ static void sixlowpan_compress_ipv6hdr(FAR const struct ipv6_hdr_s *ipv6hdr,
#ifdef CONFIG_NET_UDP
case IP_PROTO_UDP:
protosize = sizeof(struct udp_hdr_s);
protosize = UDP_HDRLEN;
break;
#endif
#ifdef CONFIG_NET_ICMPv6
case IP_PROTO_ICMP6:
protosize = sizeof(struct icmpv6_hdr_s);
protosize = ICMPv6_HDRLEN;
break;
#endif
default:
nwarn("WARNING: Unrecognized proto: %u\n", ipv6hdr->proto);
return;
return 0;
}
}
/* Copy the protocol header. */
memcpy(fptr + g_frame_hdrlen, (FAR uint8_t *)ipv6hdr + g_uncomp_hdrlen,
protosize);
g_frame_hdrlen += protosize;
g_uncomp_hdrlen += protosize;
return protosize;
}
/****************************************************************************
@ -234,6 +249,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
#ifdef CONFIG_NET_6LOWPAN_FRAG
uint16_t outlen = 0;
#endif
uint8_t protosize;
int ret;
ninfo("buflen=%lu\n", (unsigned long)buflen);
@ -244,6 +260,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
g_uncomp_hdrlen = 0;
g_frame_hdrlen = 0;
g_have_protohdr = false;
/* Reset frame meta data */
@ -381,9 +398,13 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
ninfo("Header of length %d\n", g_frame_hdrlen);
/* Get the size of any uncompressed protocol headers */
protosize = sixlowpan_protosize(destip, fptr);
/* Check if we need to fragment the packet into several frames */
if (buflen > (SIXLOWPAN_FRAMELEN - g_frame_hdrlen))
if (buflen > (SIXLOWPAN_FRAMELEN - g_frame_hdrlen - protosize))
{
#ifdef CONFIG_NET_6LOWPAN_FRAG
/* qhead will hold the generated frame list; frames will be
@ -430,19 +451,29 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
* bytes for all subsequent headers.
*/
pktlen = buflen + g_uncomp_hdrlen;
pktlen = buflen + g_uncomp_hdrlen + protosize;
PUTHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE,
((SIXLOWPAN_DISPATCH_FRAG1 << 8) | pktlen));
PUTHOST16(fragptr, SIXLOWPAN_FRAG_TAG, ieee->i_dgramtag);
g_frame_hdrlen += SIXLOWPAN_FRAG1_HDR_LEN;
/* Copy any uncompressed protocol headers that must appear only in th
* first fragment.
*/
if (protosize > 0)
{
FAR uint8_t *src = (FAR uint8_t *)destip + IPv6_HDRLEN;
memcpy(fptr + g_frame_hdrlen, src, protosize);
}
/* Copy payload and enqueue. NOTE that the size is a multiple of eight
* bytes.
*/
paysize = (SIXLOWPAN_FRAMELEN - g_frame_hdrlen) & ~7;
memcpy(fptr + g_frame_hdrlen, buf, paysize);
memcpy(fptr + g_frame_hdrlen + protosize, buf, paysize - protosize);
/* Set outlen to what we already sent from the IP payload */
@ -471,7 +502,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
frame1 = iob->io_data;
frag1_hdrlen = g_frame_hdrlen;
while (outlen < buflen)
while (outlen < (buflen + protosize))
{
uint16_t fragn_hdrlen;
@ -515,14 +546,14 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
paysize = (SIXLOWPAN_FRAMELEN - fragn_hdrlen) &
SIXLOWPAN_DISPATCH_FRAG_MASK;
if (buflen - outlen < paysize)
if (paysize > buflen - outlen + protosize)
{
/* Last fragment, truncate to the correct length */
paysize = buflen - outlen;
paysize = buflen - outlen + protosize;
}
memcpy(fptr + fragn_hdrlen, buf + outlen, paysize);
memcpy(fptr + fragn_hdrlen, buf + outlen - protosize, paysize);
/* Set outlen to what we already sent from the IP payload */
@ -587,10 +618,20 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
* and send in one frame.
*/
/* Copy any uncompressed protocol headers that must appear only in th
* first fragment.
*/
if (protosize > 0)
{
FAR uint8_t *src = (FAR uint8_t *)destip + IPv6_HDRLEN;
memcpy(fptr + g_frame_hdrlen, src, protosize);
}
/* Copy the payload into the frame. */
memcpy(fptr + g_frame_hdrlen, buf, buflen);
iob->io_len = buflen + g_frame_hdrlen;
memcpy(fptr + g_frame_hdrlen + protosize, buf, buflen);
iob->io_len = buflen + g_frame_hdrlen + protosize;
iob->io_pktlen = iob->io_len;
ninfo("Non-fragmented: length %d\n", iob->io_len);

View file

@ -67,4 +67,8 @@ uint8_t g_uncomp_hdrlen;
uint8_t g_frame_hdrlen;
/* g_have_protohdr: true=Protocal header copied. */
bool g_have_protohdr;
#endif /* CONFIG_NET_6LOWPAN */

View file

@ -878,14 +878,10 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
g_uncomp_hdrlen = IPv6_HDRLEN;
/* Add protocol header */
switch (ipv6->proto)
{
#ifdef CONFIG_NET_UDP
/* UDP header compression */
case IP_PROTO_UDP:
if (ipv6->proto == IP_PROTO_UDP)
{
/* The UDP header will follow the IPv6 header */
@ -957,54 +953,13 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
/* Always inline the checksum */
if (1)
{
memcpy(g_hc06ptr, &udp->udpchksum, 2);
g_hc06ptr += 2;
}
g_uncomp_hdrlen += UDP_HDRLEN;
g_have_protohdr = true;
}
break;
#endif /* CONFIG_NET_UDP */
#ifdef CONFIG_NET_TCP
/* TCP header -- not compressed */
case IP_PROTO_TCP:
{
FAR struct tcp_hdr_s *tcp =
(FAR struct tcp_hdr_s *)((FAR uint8_t *)ipv6 + IPv6_HDRLEN);
unsigned int hdrsize;
hdrsize = ((uint16_t)tcp->tcpoffset >> 4) << 2;
memcpy(g_hc06ptr, tcp, hdrsize);
g_uncomp_hdrlen += hdrsize;
g_hc06ptr += hdrsize;
}
break;
#endif
#ifdef CONFIG_NET_ICMPv6
/* TCP header -- not compressed */
case IP_PROTO_ICMP:
{
FAR const uint8_t *src = (FAR const uint8_t *)ipv6 + IPv6_HDRLEN;
memcpy(g_hc06ptr, src, ICMPv6_HDRLEN)
g_uncomp_hdrlen += ICMPv6_HDRLEN;
g_hc06ptr += ICMPv6_HDRLEN;
}
break;
#endif
default:
nerr("ERROR: Unsupported protocol: %02x\n", ipv6->proto);
break;
}
/* Before the g_frame_hdrlen operation */
iphc[0] = iphc0;

View file

@ -265,6 +265,8 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
hc1[SIXLOWPAN_HC1_TTL] = ipv6->ttl;
g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
}
g_have_protohdr = true;
}
break;
#endif /* CONFIG_NET_UDP */

View file

@ -58,7 +58,9 @@
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdbool.h>
#include <nuttx/net/tcp.h>
#include <nuttx/net/udp.h>
@ -207,6 +209,10 @@ extern uint8_t g_uncomp_hdrlen;
extern uint8_t g_frame_hdrlen;
/* g_have_protohdr: true=Protocal header copied. */
extern bool g_have_protohdr;
/****************************************************************************
* Public Types
****************************************************************************/