6LoWPAN: HC06, copy TCP header as though it were data.

This commit is contained in:
Gregory Nutt 2017-06-24 18:29:07 -06:00
parent 74c97f7e7f
commit 73d32a962d
3 changed files with 130 additions and 96 deletions

View File

@ -878,91 +878,133 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
g_uncomp_hdrlen = IPv6_HDRLEN;
#ifdef CONFIG_NET_UDP
/* UDP header compression */
/* Add protocol header */
if (ipv6->proto == IP_PROTO_UDP)
switch (ipv6->proto)
{
/* The UDP header will follow the IPv6 header */
#ifdef CONFIG_NET_UDP
/* UDP header compression */
FAR struct udp_hdr_s *udp =
(FAR struct udp_hdr_s *)((FAR uint8_t *)ipv6 + IPv6_HDRLEN);
ninfo("Uncompressed UDP ports: srcport=%04x destport=%04x\n",
ntohs(udp->srcport), ntohs(udp->destport));
/* Mask out the last 4 bits can be used as a mask */
if (((ntohs(udp->srcport) & 0xfff0) == SIXLOWPAN_UDP_4_BIT_PORT_MIN) &&
((ntohs(udp->destport) & 0xfff0) == SIXLOWPAN_UDP_4_BIT_PORT_MIN))
case IP_PROTO_UDP:
{
/* We can compress 12 bits of both source and dest */
/* The UDP header will follow the IPv6 header */
*g_hc06ptr = SIXLOWPAN_NHC_UDP_CS_P_11;
FAR struct udp_hdr_s *udp =
(FAR struct udp_hdr_s *)((FAR uint8_t *)ipv6 + IPv6_HDRLEN);
ninfo("Remove 12b of both source & dest with prefix 0xf0b*\n");
ninfo("Uncompressed UDP ports: srcport=%04x destport=%04x\n",
ntohs(udp->srcport), ntohs(udp->destport));
*(g_hc06ptr + 1) =
(uint8_t)((ntohs(udp->srcport) - SIXLOWPAN_UDP_4_BIT_PORT_MIN) << 4) +
(uint8_t)((ntohs(udp->destport) - SIXLOWPAN_UDP_4_BIT_PORT_MIN));
/* Mask out the last 4 bits can be used as a mask */
g_hc06ptr += 2;
if (((ntohs(udp->srcport) & 0xfff0) == SIXLOWPAN_UDP_4_BIT_PORT_MIN) &&
((ntohs(udp->destport) & 0xfff0) == SIXLOWPAN_UDP_4_BIT_PORT_MIN))
{
/* We can compress 12 bits of both source and dest */
*g_hc06ptr = SIXLOWPAN_NHC_UDP_CS_P_11;
ninfo("Remove 12b of both source & dest with prefix 0xf0b*\n");
*(g_hc06ptr + 1) =
(uint8_t)((ntohs(udp->srcport) - SIXLOWPAN_UDP_4_BIT_PORT_MIN) << 4) +
(uint8_t)((ntohs(udp->destport) - SIXLOWPAN_UDP_4_BIT_PORT_MIN));
g_hc06ptr += 2;
}
else if ((ntohs(udp->destport) & 0xff00) ==
SIXLOWPAN_UDP_8_BIT_PORT_MIN)
{
/* We can compress 8 bits of dest, leave source. */
*g_hc06ptr = SIXLOWPAN_NHC_UDP_CS_P_01;
ninfo("Leave source, remove 8 bits of dest with prefix 0xF0\n");
memcpy(g_hc06ptr + 1, &udp->srcport, 2);
*(g_hc06ptr + 3) =
(uint8_t) ((ntohs(udp->destport) -
SIXLOWPAN_UDP_8_BIT_PORT_MIN));
g_hc06ptr += 4;
}
else if ((ntohs(udp->srcport) & 0xff00) ==
SIXLOWPAN_UDP_8_BIT_PORT_MIN)
{
/* We can compress 8 bits of src, leave dest. Copy compressed port */
*g_hc06ptr = SIXLOWPAN_NHC_UDP_CS_P_10;
ninfo("Remove 8 bits of source with prefix 0xF0, leave dest. hch: %u\n",
*g_hc06ptr);
*(g_hc06ptr + 1) =
(uint8_t)((ntohs(udp->srcport) - SIXLOWPAN_UDP_8_BIT_PORT_MIN));
memcpy(g_hc06ptr + 2, &udp->destport, 2);
g_hc06ptr += 4;
}
else
{
/* we cannot compress. Copy uncompressed ports, full checksum */
*g_hc06ptr = SIXLOWPAN_NHC_UDP_CS_P_00;
nwarn("WARNING: Cannot compress headers\n");
memcpy(g_hc06ptr + 1, &udp->srcport, 4);
g_hc06ptr += 5;
}
/* Always inline the checksum */
if (1)
{
memcpy(g_hc06ptr, &udp->udpchksum, 2);
g_hc06ptr += 2;
}
g_uncomp_hdrlen += UDP_HDRLEN;
}
else if ((ntohs(udp->destport) & 0xff00) ==
SIXLOWPAN_UDP_8_BIT_PORT_MIN)
{
/* We can compress 8 bits of dest, leave source. */
*g_hc06ptr = SIXLOWPAN_NHC_UDP_CS_P_01;
ninfo("Leave source, remove 8 bits of dest with prefix 0xF0\n");
memcpy(g_hc06ptr + 1, &udp->srcport, 2);
*(g_hc06ptr + 3) =
(uint8_t) ((ntohs(udp->destport) -
SIXLOWPAN_UDP_8_BIT_PORT_MIN));
g_hc06ptr += 4;
}
else if ((ntohs(udp->srcport) & 0xff00) ==
SIXLOWPAN_UDP_8_BIT_PORT_MIN)
{
/* We can compress 8 bits of src, leave dest. Copy compressed port */
*g_hc06ptr = SIXLOWPAN_NHC_UDP_CS_P_10;
ninfo("Remove 8 bits of source with prefix 0xF0, leave dest. hch: %u\n",
*g_hc06ptr);
*(g_hc06ptr + 1) =
(uint8_t)((ntohs(udp->srcport) - SIXLOWPAN_UDP_8_BIT_PORT_MIN));
memcpy(g_hc06ptr + 2, &udp->destport, 2);
g_hc06ptr += 4;
}
else
{
/* we cannot compress. Copy uncompressed ports, full checksum */
*g_hc06ptr = SIXLOWPAN_NHC_UDP_CS_P_00;
nwarn("WARNING: Cannot compress headers\n");
memcpy(g_hc06ptr + 1, &udp->srcport, 4);
g_hc06ptr += 5;
}
/* Always inline the checksum */
if (1)
{
memcpy(g_hc06ptr, &udp->udpchksum, 2);
g_hc06ptr += 2;
}
g_uncomp_hdrlen += UDP_HDRLEN;
}
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;
@ -1199,7 +1241,7 @@ void sixlowpan_uncompresshdr_hc06(FAR const struct ieee802154_data_ind_s *ind,
}
else
{
/* no multicast */
/* No multicast */
/* Context based */
if ((iphc1 & SIXLOWPAN_IPHC_DAC) != 0)

View File

@ -475,13 +475,15 @@ static uint16_t tcp_send_interrupt(FAR struct net_driver_s *dev,
{
uint32_t seqno;
uint16_t winleft;
uint16_t sndlen;
DEBUGASSERT((flags & WPAN_POLL) != 0);
/* Get the amount of data that we can send in the next packet */
uint32_t sndlen = sinfo->s_buflen - sinfo->s_sent;
/* Get the amount of TCP payload data that we can send in the next
* packet.
*/
sndlen = sinfo->s_buflen - sinfo->s_sent;
if (sndlen > conn->mss)
{
sndlen = conn->mss;
@ -493,8 +495,8 @@ static uint16_t tcp_send_interrupt(FAR struct net_driver_s *dev,
sndlen = winleft;
}
ninfo("s_buflen=%u s_sent=%u mss=%u winsize=%u\n",
sinfo->s_buflen, sinfo->s_sent, conn->mss, conn->winsize);
ninfo("s_buflen=%u s_sent=%u mss=%u winsize=%u sndlen=%d\n",
sinfo->s_buflen, sinfo->s_sent, conn->mss, conn->winsize, sndlen);
if (sndlen > 0)
{
@ -506,7 +508,9 @@ static uint16_t tcp_send_interrupt(FAR struct net_driver_s *dev,
*/
seqno = sinfo->s_sent + sinfo->s_isn;
ninfo("SEND: sndseq %08x->%08x\n", conn->sndseq, seqno);
ninfo("Sending: sndseq %08lx->%08x\n",
(unsigned long)tcp_getsequence(conn->sndseq), seqno);
tcp_setsequence(conn->sndseq, seqno);
/* Create the IPv6 + TCP header */

View File

@ -131,16 +131,6 @@ static uint8_t g_panid[IEEE802154_PANIDSIZE] =
0xca, 0xfe
};
static const uint8_t g_src_eaddr[IEEE802154_EADDRSIZE] =
{
0x0a, 0xfa, 0xde, 0x00, 0xde, 0xad, 0xbe, 0xef
};
static const uint8_t g_src_saddr[IEEE802154_SADDRSIZE] =
{
0x12, 0x34
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
@ -311,13 +301,11 @@ static int lo_loopback(FAR struct net_driver_s *dev)
ind.dest.mode = IEEE802154_ADDRMODE_SHORT;
#endif
/* Only loopback the local address is the destination and some (arbitrary)
* address is the source.
*/
/* On loopback the local address is both the source and destination. */
IEEE802154_PANIDCOPY(ind.src.panid, g_panid);
IEEE802154_SADDRCOPY(ind.src.saddr, g_src_saddr);
IEEE802154_EADDRCOPY(ind.src.eaddr, g_src_eaddr);
IEEE802154_SADDRCOPY(ind.src.saddr, g_saddr);
IEEE802154_EADDRCOPY(ind.src.eaddr, g_eaddr);
IEEE802154_PANIDCOPY(ind.dest.panid, g_panid);
IEEE802154_SADDRCOPY(ind.dest.saddr, g_saddr);