Removed unused include files (also automatically removed whitespace from line endings)

This commit is contained in:
adamdunkels 2008-10-14 12:26:18 +00:00
parent 573040e315
commit fc1a8575d6
3 changed files with 177 additions and 183 deletions

View File

@ -32,7 +32,7 @@
* *
* This file is part of the Contiki operating system. * This file is part of the Contiki operating system.
* *
* $Id: sicslowpan.c,v 1.1 2008/10/14 09:42:33 julienabeille Exp $ * $Id: sicslowpan.c,v 1.2 2008/10/14 12:26:18 adamdunkels Exp $
*/ */
/** /**
* \file * \file
@ -53,8 +53,6 @@
#include "net/rime.h" #include "net/rime.h"
#include "net/sicslowpan.h" #include "net/sicslowpan.h"
#include <util/delay.h>
#define DEBUG 0 #define DEBUG 0
#if DEBUG #if DEBUG
@ -70,8 +68,8 @@ u8_t p;
#define PRINTF(...) #define PRINTF(...)
#define PRINT6ADDR(addr) #define PRINT6ADDR(addr)
#define PRINTLLADDR(lladdr) #define PRINTLLADDR(lladdr)
#define PRINTRIMEBUF() #define PRINTRIMEBUF()
#define PRINTUIPBUF() #define PRINTUIPBUF()
#define PRINTSICSLOWPANBUF() #define PRINTSICSLOWPANBUF()
#endif /* DEBUG == 1*/ #endif /* DEBUG == 1*/
@ -113,9 +111,9 @@ void uip_log(char *msg);
/** A pointer to the mac driver */ /** A pointer to the mac driver */
static const struct mac_driver *mac; static const struct mac_driver *mac;
/** /**
* A pointer to the rime buffer. * A pointer to the rime buffer.
* We initialize it to the beginning of the rime buffer, then * We initialize it to the beginning of the rime buffer, then
* access different fields by updating the offset rime_hdr_len. * access different fields by updating the offset rime_hdr_len.
*/ */
static u8_t *rime_ptr; static u8_t *rime_ptr;
@ -123,15 +121,15 @@ static u8_t *rime_ptr;
/** /**
* rime_hdr_len is the total length of (the processed) 6lowpan headers * rime_hdr_len is the total length of (the processed) 6lowpan headers
* (fragment headers, IPV6 or HC1, HC2, and HC1 and HC2 non compressed * (fragment headers, IPV6 or HC1, HC2, and HC1 and HC2 non compressed
* fields). * fields).
*/ */
static u8_t rime_hdr_len; static u8_t rime_hdr_len;
/** /**
* The length of the payload in the Rime buffer. * The length of the payload in the Rime buffer.
* The payload is what comes after the compressed or uncompressed * The payload is what comes after the compressed or uncompressed
* headers (can be the IP payload if the IP header only is compressed * headers (can be the IP payload if the IP header only is compressed
* or the UDP payload if the UDP header is also compressed) * or the UDP payload if the UDP header is also compressed)
*/ */
static u8_t rime_payload_len; static u8_t rime_payload_len;
@ -151,7 +149,7 @@ static u8_t uncomp_hdr_len;
* This buffer contains only the IPv6 packet (no MAC header, 6lowpan, etc). * This buffer contains only the IPv6 packet (no MAC header, 6lowpan, etc).
* It has a fix size as we do not use dynamic memory allocation. * It has a fix size as we do not use dynamic memory allocation.
*/ */
static u8_t sicslowpan_buf[UIP_BUFSIZE]; static u8_t sicslowpan_buf[UIP_BUFSIZE];
/** The total length of the IPv6 packet in the sicslowpan_buf. */ /** The total length of the IPv6 packet in the sicslowpan_buf. */
static u16_t sicslowpan_len; static u16_t sicslowpan_len;
@ -184,7 +182,7 @@ static struct timer reass_timer;
#endif /* SICSLOWPAN_CONF_FRAG */ #endif /* SICSLOWPAN_CONF_FRAG */
#if SICSLOWPAN_CONF_COMPRESSION == SICSLOWPAN_CONF_COMPRESSION_HC01 #if SICSLOWPAN_CONF_COMPRESSION == SICSLOWPAN_CONF_COMPRESSION_HC01
/** \name HC01 specific variables /** \name HC01 specific variables
* @{ * @{
*/ */
@ -204,41 +202,41 @@ static u8_t i;
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
/** \name HC01 related functions /** \name HC01 related functions
* @{ */ * @{ */
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
/** \brief find the context corresponding to prefix ipaddr */ /** \brief find the context corresponding to prefix ipaddr */
static struct sicslowpan_addr_context* static struct sicslowpan_addr_context*
addr_context_lookup_by_prefix(uip_ipaddr_t *ipaddr) { addr_context_lookup_by_prefix(uip_ipaddr_t *ipaddr) {
for(i = 0; i < SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS; i++) { for(i = 0; i < SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS; i++) {
if((addr_contexts[i].used == 1) && if((addr_contexts[i].used == 1) &&
uip_ipaddr_prefixcmp(&addr_contexts[i].prefix, ipaddr, 64)) { uip_ipaddr_prefixcmp(&addr_contexts[i].prefix, ipaddr, 64)) {
return &addr_contexts[i]; return &addr_contexts[i];
} }
} }
return NULL; return NULL;
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
/** \brief find the context with the given number */ /** \brief find the context with the given number */
static struct sicslowpan_addr_context* static struct sicslowpan_addr_context*
addr_context_lookup_by_number(u8_t number) { addr_context_lookup_by_number(u8_t number) {
for(i = 0; i < SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS; i++) { for(i = 0; i < SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS; i++) {
if((addr_contexts[i].used == 1) && if((addr_contexts[i].used == 1) &&
addr_contexts[i].number == number) { addr_contexts[i].number == number) {
return &addr_contexts[i]; return &addr_contexts[i];
} }
} }
return NULL; return NULL;
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
/** /**
* \brief Compress IP/UDP header * \brief Compress IP/UDP header
* *
* This function is called by the 6lowpan code to create a compressed * This function is called by the 6lowpan code to create a compressed
* 6lowpan packet in the rimebuf buffer from a full IPv6 packet in the * 6lowpan packet in the rimebuf buffer from a full IPv6 packet in the
* uip_buf buffer. * uip_buf buffer.
* *
* *
* HC01 (draft-hui-6lowpan-hc, version 1)\n * HC01 (draft-hui-6lowpan-hc, version 1)\n
* *
* \note We do not support ISA100_UDP header compression * \note We do not support ISA100_UDP header compression
@ -268,17 +266,17 @@ addr_context_lookup_by_number(u8_t number) {
* Address compression logic (multicast only applies to dest): * Address compression logic (multicast only applies to dest):
* If multicast: * If multicast:
* If flags (see RFC4291 section 2.7) are all 0 AND * If flags (see RFC4291 section 2.7) are all 0 AND
* the 112-bit group id is mapable to a 9-bit group * the 112-bit group id is mapable to a 9-bit group
* (for now all nodes and all routers groups are * (for now all nodes and all routers groups are
* mapable), * mapable),
* we compress to 16 bits * we compress to 16 bits
* Else unicast: * Else unicast:
* If we have a context for the prefix, * If we have a context for the prefix,
* we elide 64 bits prefix. * we elide 64 bits prefix.
* If the IID can be inferred from lower layers, * If the IID can be inferred from lower layers,
* we elide 64 bits IID * we elide 64 bits IID
* else * else
* if first 49 bits of IID are 0, * if first 49 bits of IID are 0,
* we compress IID to 16 bits (with first = 0 * we compress IID to 16 bits (with first = 0
* to differentiate from multicast) * to differentiate from multicast)
* *
@ -289,18 +287,18 @@ compress_hdr_hc01(rimeaddr_t *rime_destaddr)
hc01_ptr = rime_ptr + 3; hc01_ptr = rime_ptr + 3;
/* /*
* As we copy some bit-length fields, in the IPHC encoding bytes, * As we copy some bit-length fields, in the IPHC encoding bytes,
* we sometimes use |= * we sometimes use |=
* If the field is 0, and the current bit value in memory is 1, * If the field is 0, and the current bit value in memory is 1,
* this does not work. We therefore reset the IPHC encoding here * this does not work. We therefore reset the IPHC encoding here
*/ */
memset(RIME_IPHC_BUF->encoding, 0, 2); memset(RIME_IPHC_BUF->encoding, 0, 2);
RIME_IPHC_BUF->dispatch = SICSLOWPAN_DISPATCH_IPHC; RIME_IPHC_BUF->dispatch = SICSLOWPAN_DISPATCH_IPHC;
/* /*
* Version, traffic class, flow label * Version, traffic class, flow label
* If flow label is 0, compress it. If traffic class is 0, compress it * If flow label is 0, compress it. If traffic class is 0, compress it
* We have to process both in the same time as the offset of traffic class * We have to process both in the same time as the offset of traffic class
* depends on the presence of version and flow label * depends on the presence of version and flow label
*/ */
if(((UIP_IP_BUF->tcflow & 0x0F) == 0) && if(((UIP_IP_BUF->tcflow & 0x0F) == 0) &&
(UIP_IP_BUF->flow == 0)) { (UIP_IP_BUF->flow == 0)) {
@ -308,7 +306,7 @@ compress_hdr_hc01(rimeaddr_t *rime_destaddr)
RIME_IPHC_BUF->encoding[0] |= SICSLOWPAN_IPHC_VF_C; RIME_IPHC_BUF->encoding[0] |= SICSLOWPAN_IPHC_VF_C;
if(((UIP_IP_BUF->vtc & 0x0F) == 0) && if(((UIP_IP_BUF->vtc & 0x0F) == 0) &&
((UIP_IP_BUF->tcflow & 0xF0) == 0)) { ((UIP_IP_BUF->tcflow & 0xF0) == 0)) {
/* compress (elide) all */ /* compress (elide) all */
RIME_IPHC_BUF->encoding[0] |= SICSLOWPAN_IPHC_TC_C; RIME_IPHC_BUF->encoding[0] |= SICSLOWPAN_IPHC_TC_C;
} else { } else {
/* compress only version and flow label */ /* compress only version and flow label */
@ -324,11 +322,11 @@ compress_hdr_hc01(rimeaddr_t *rime_destaddr)
RIME_IPHC_BUF->encoding[0] |= SICSLOWPAN_IPHC_TC_C; RIME_IPHC_BUF->encoding[0] |= SICSLOWPAN_IPHC_TC_C;
*hc01_ptr = (UIP_IP_BUF->vtc & 0xF0) | *hc01_ptr = (UIP_IP_BUF->vtc & 0xF0) |
(UIP_IP_BUF->tcflow & 0x0F); (UIP_IP_BUF->tcflow & 0x0F);
memcpy(hc01_ptr + 1, &UIP_IP_BUF->flow, 2); memcpy(hc01_ptr + 1, &UIP_IP_BUF->flow, 2);
hc01_ptr += 3; hc01_ptr += 3;
} else { } else {
/* compress nothing */ /* compress nothing */
memcpy(hc01_ptr, &UIP_IP_BUF->vtc, 4); memcpy(hc01_ptr, &UIP_IP_BUF->vtc, 4);
hc01_ptr += 4; hc01_ptr += 4;
} }
} }
@ -344,11 +342,11 @@ compress_hdr_hc01(rimeaddr_t *rime_destaddr)
*hc01_ptr = UIP_IP_BUF->proto; *hc01_ptr = UIP_IP_BUF->proto;
hc01_ptr += 1; hc01_ptr += 1;
#if UIP_CONF_UDP #if UIP_CONF_UDP
} }
#endif /*UIP_CONF_UDP*/ #endif /*UIP_CONF_UDP*/
/* /*
* Hop limit * Hop limit
* if 1: compress, encoding is 01 * if 1: compress, encoding is 01
* if 64: compress, encoding is 10 * if 64: compress, encoding is 10
* if 255: compress, encoding is 11 * if 255: compress, encoding is 11
@ -370,7 +368,7 @@ compress_hdr_hc01(rimeaddr_t *rime_destaddr)
break; break;
} }
/* source address - cannot be multicast */ /* source address - cannot be multicast */
if((context = addr_context_lookup_by_prefix(&UIP_IP_BUF->srcipaddr)) if((context = addr_context_lookup_by_prefix(&UIP_IP_BUF->srcipaddr))
!= NULL) { != NULL) {
/* elide the prefix */ /* elide the prefix */
@ -402,14 +400,14 @@ compress_hdr_hc01(rimeaddr_t *rime_destaddr)
if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) { if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
/* Address is multicast, try to compress */ /* Address is multicast, try to compress */
if(sicslowpan_is_mcast_addr_compressable(&UIP_IP_BUF->destipaddr)) { if(sicslowpan_is_mcast_addr_compressable(&UIP_IP_BUF->destipaddr)) {
RIME_IPHC_BUF->encoding[1] |= SICSLOWPAN_IPHC_DAM_16; RIME_IPHC_BUF->encoding[1] |= SICSLOWPAN_IPHC_DAM_16;
/* 3 first bits = 101 */ /* 3 first bits = 101 */
*hc01_ptr = SICSLOWPAN_IPHC_MCAST_RANGE; *hc01_ptr = SICSLOWPAN_IPHC_MCAST_RANGE;
/* bits 3-6 = scope = bits 8-11 in 128 bits address */ /* bits 3-6 = scope = bits 8-11 in 128 bits address */
*hc01_ptr |= (UIP_IP_BUF->destipaddr.u8[1] & 0x0F) << 1; *hc01_ptr |= (UIP_IP_BUF->destipaddr.u8[1] & 0x0F) << 1;
/* /*
* bits 7 - 15 = 9-bit group * bits 7 - 15 = 9-bit group
* We just copy the last byte because it works * We just copy the last byte because it works
* with currently supported groups * with currently supported groups
*/ */
*(hc01_ptr + 1) = UIP_IP_BUF->destipaddr.u8[15]; *(hc01_ptr + 1) = UIP_IP_BUF->destipaddr.u8[15];
@ -457,8 +455,8 @@ compress_hdr_hc01(rimeaddr_t *rime_destaddr)
HTONS(UIP_UDP_BUF->srcport) < SICSLOWPAN_UDP_PORT_MAX && HTONS(UIP_UDP_BUF->srcport) < SICSLOWPAN_UDP_PORT_MAX &&
HTONS(UIP_UDP_BUF->destport) >= SICSLOWPAN_UDP_PORT_MIN && HTONS(UIP_UDP_BUF->destport) >= SICSLOWPAN_UDP_PORT_MIN &&
HTONS(UIP_UDP_BUF->destport) < SICSLOWPAN_UDP_PORT_MAX) { HTONS(UIP_UDP_BUF->destport) < SICSLOWPAN_UDP_PORT_MAX) {
/* we can compress. Copy compressed ports, full chcksum */ /* we can compress. Copy compressed ports, full chcksum */
*hc01_ptr = SICSLOWPAN_NHC_UDP_C; *hc01_ptr = SICSLOWPAN_NHC_UDP_C;
*(hc01_ptr + 1) = *(hc01_ptr + 1) =
(u8_t)((HTONS(UIP_UDP_BUF->srcport) - (u8_t)((HTONS(UIP_UDP_BUF->srcport) -
SICSLOWPAN_UDP_PORT_MIN) << 4) + SICSLOWPAN_UDP_PORT_MIN) << 4) +
@ -467,16 +465,16 @@ compress_hdr_hc01(rimeaddr_t *rime_destaddr)
memcpy(hc01_ptr + 2, &UIP_UDP_BUF->udpchksum, 2); memcpy(hc01_ptr + 2, &UIP_UDP_BUF->udpchksum, 2);
hc01_ptr += 4; hc01_ptr += 4;
} else { } else {
/* we cannot compress. Copy uncompressed ports, full chcksum */ /* we cannot compress. Copy uncompressed ports, full chcksum */
*hc01_ptr = SICSLOWPAN_NHC_UDP_I; *hc01_ptr = SICSLOWPAN_NHC_UDP_I;
memcpy(hc01_ptr + 1, &UIP_UDP_BUF->srcport, 4); memcpy(hc01_ptr + 1, &UIP_UDP_BUF->srcport, 4);
memcpy(hc01_ptr + 5, &UIP_UDP_BUF->udpchksum, 2); memcpy(hc01_ptr + 5, &UIP_UDP_BUF->udpchksum, 2);
hc01_ptr += 7; hc01_ptr += 7;
} }
uncomp_hdr_len += UIP_UDPH_LEN; uncomp_hdr_len += UIP_UDPH_LEN;
} }
#endif /*UIP_CONF_UDP*/ #endif /*UIP_CONF_UDP*/
rime_hdr_len = hc01_ptr - rime_ptr; rime_hdr_len = hc01_ptr - rime_ptr;
return; return;
} }
@ -486,7 +484,7 @@ compress_hdr_hc01(rimeaddr_t *rime_destaddr)
* them in sicslowpan_buf * them in sicslowpan_buf
* *
* This function is called by the input function when the dispatch is * This function is called by the input function when the dispatch is
* HC01. * HC01.
* We %process the packet in the rime buffer, uncompress the header * We %process the packet in the rime buffer, uncompress the header
* fields, and copy the result in the sicslowpan buffer. * fields, and copy the result in the sicslowpan buffer.
* At the end of the decompression, rime_hdr_len and uncompressed_hdr_len * At the end of the decompression, rime_hdr_len and uncompressed_hdr_len
@ -501,14 +499,14 @@ compress_hdr_hc01(rimeaddr_t *rime_destaddr)
* - IP header * - IP header
* We process the fields in their order of appearance in the normal * We process the fields in their order of appearance in the normal
* IP header, with two exceptions: * IP header, with two exceptions:
* - next header: field when it is compressed: we need to reach the * - next header: field when it is compressed: we need to reach the
* NHC encoding to know which is the next header * NHC encoding to know which is the next header
* - length: we need to know the length of headers in rime buffer * - length: we need to know the length of headers in rime buffer
* (i.e. the final value of rime_hdr_len) * (i.e. the final value of rime_hdr_len)
* - Addresses processing * - Addresses processing
* We do the same for src and dest, even though a multicast source * We do the same for src and dest, even though a multicast source
* address is wrong. IP layer will handle this. The logic is: * address is wrong. IP layer will handle this. The logic is:
* *
* Switch(compression) * Switch(compression)
* case no compression: copy full address * case no compression: copy full address
* case 64bit compressed address: * case 64bit compressed address:
@ -523,11 +521,11 @@ compress_hdr_hc01(rimeaddr_t *rime_destaddr)
* then 16 last bits from packet * then 16 last bits from packet
* else (multicast case) * else (multicast case)
* first byte = FF, flags = 0, copy scope * first byte = FF, flags = 0, copy scope
* from packet, infer 112 bits group ID from * from packet, infer 112 bits group ID from
* 9 bit group id * 9 bit group id
* *
* - UDP header, for LOWPAN_UDP compression * - UDP header, for LOWPAN_UDP compression
* The only trick is that we fill the length field at the end of * The only trick is that we fill the length field at the end of
* the function. * the function.
*/ */
@ -600,7 +598,7 @@ uncompress_hdr_hc01(u16_t ip_len) {
/* copy prefix from context */ /* copy prefix from context */
memcpy(&SICSLOWPAN_IP_BUF->srcipaddr, context->prefix, 8); memcpy(&SICSLOWPAN_IP_BUF->srcipaddr, context->prefix, 8);
/* infer IID from L2 address */ /* infer IID from L2 address */
uip_netif_addr_autoconf_set(&SICSLOWPAN_IP_BUF->srcipaddr, uip_netif_addr_autoconf_set(&SICSLOWPAN_IP_BUF->srcipaddr,
(uip_lladdr_t *)rimebuf_addr(RIMEBUF_ADDR_SENDER)); (uip_lladdr_t *)rimebuf_addr(RIMEBUF_ADDR_SENDER));
break; break;
case SICSLOWPAN_IPHC_SAM_16: case SICSLOWPAN_IPHC_SAM_16:
@ -636,7 +634,7 @@ uncompress_hdr_hc01(u16_t ip_len) {
} }
/* copy prefix from context */ /* copy prefix from context */
memcpy(&SICSLOWPAN_IP_BUF->srcipaddr, context->prefix, 8); memcpy(&SICSLOWPAN_IP_BUF->srcipaddr, context->prefix, 8);
/* copy IID from packet */ /* copy IID from packet */
memcpy(&SICSLOWPAN_IP_BUF->srcipaddr.u8[8], hc01_ptr, 8); memcpy(&SICSLOWPAN_IP_BUF->srcipaddr.u8[8], hc01_ptr, 8);
hc01_ptr += 8; hc01_ptr += 8;
break; break;
@ -659,7 +657,7 @@ uncompress_hdr_hc01(u16_t ip_len) {
/* copy prefix from context */ /* copy prefix from context */
memcpy(&SICSLOWPAN_IP_BUF->destipaddr, context->prefix, 8); memcpy(&SICSLOWPAN_IP_BUF->destipaddr, context->prefix, 8);
/* infer IID from L2 address */ /* infer IID from L2 address */
uip_netif_addr_autoconf_set(&SICSLOWPAN_IP_BUF->destipaddr, uip_netif_addr_autoconf_set(&SICSLOWPAN_IP_BUF->destipaddr,
(uip_lladdr_t *)rimebuf_addr(RIMEBUF_ADDR_RECEIVER)); (uip_lladdr_t *)rimebuf_addr(RIMEBUF_ADDR_RECEIVER));
break; break;
case SICSLOWPAN_IPHC_DAM_16: case SICSLOWPAN_IPHC_DAM_16:
@ -705,7 +703,7 @@ uncompress_hdr_hc01(u16_t ip_len) {
} }
uncomp_hdr_len += UIP_IPH_LEN; uncomp_hdr_len += UIP_IPH_LEN;
/* Next header processing - continued */ /* Next header processing - continued */
if((RIME_IPHC_BUF->encoding[0] & 0x20) != 0) { if((RIME_IPHC_BUF->encoding[0] & 0x20) != 0) {
/* The next header is compressed, NHC is following */ /* The next header is compressed, NHC is following */
if((*hc01_ptr & 0xFC) == SICSLOWPAN_NHC_UDP_ID) { if((*hc01_ptr & 0xFC) == SICSLOWPAN_NHC_UDP_ID) {
@ -716,7 +714,7 @@ uncompress_hdr_hc01(u16_t ip_len) {
SICSLOWPAN_UDP_BUF->srcport = HTONS(SICSLOWPAN_UDP_PORT_MIN + SICSLOWPAN_UDP_BUF->srcport = HTONS(SICSLOWPAN_UDP_PORT_MIN +
(*(hc01_ptr + 1) >> 4)); (*(hc01_ptr + 1) >> 4));
SICSLOWPAN_UDP_BUF->destport = HTONS(SICSLOWPAN_UDP_PORT_MIN + SICSLOWPAN_UDP_BUF->destport = HTONS(SICSLOWPAN_UDP_PORT_MIN +
((*(hc01_ptr + 1)) & 0x0F)); ((*(hc01_ptr + 1)) & 0x0F));
memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, hc01_ptr + 2, 2); memcpy(&SICSLOWPAN_UDP_BUF->udpchksum, hc01_ptr + 2, 2);
hc01_ptr += 4; hc01_ptr += 4;
break; break;
@ -760,7 +758,7 @@ uncompress_hdr_hc01(u16_t ip_len) {
#if SICSLOWPAN_CONF_COMPRESSION == SICSLOWPAN_CONF_COMPRESSION_HC1 #if SICSLOWPAN_CONF_COMPRESSION == SICSLOWPAN_CONF_COMPRESSION_HC1
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
/** \name HC1 compression and uncompression functions /** \name HC1 compression and uncompression functions
* @{ */ * @{ */
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
/** /**
@ -769,8 +767,8 @@ uncompress_hdr_hc01(u16_t ip_len) {
* This function is called by the 6lowpan code to create a compressed * This function is called by the 6lowpan code to create a compressed
* 6lowpan packet in the rimebuf buffer from a full IPv6 packet in the * 6lowpan packet in the rimebuf buffer from a full IPv6 packet in the
* uip_buf buffer. * uip_buf buffer.
* *
* *
* If we can compress everything, we use HC1 dispatch, if not we use * If we can compress everything, we use HC1 dispatch, if not we use
* IPv6 dispatch.\n * IPv6 dispatch.\n
* We can compress everything if: * We can compress everything if:
@ -792,10 +790,10 @@ uncompress_hdr_hc01(u16_t ip_len) {
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | LoWPAN HC1 Dsp | HC1 encoding | IPv6 Hop limit| L4 hdr + data| * | LoWPAN HC1 Dsp | HC1 encoding | IPv6 Hop limit| L4 hdr + data|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | ... * | ...
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* \endverbatim * \endverbatim
* *
* - For compressed UDP * - For compressed UDP
* HC1 encoding = 11111011, HC_UDP encoding = 11100000\n * HC1 encoding = 11111011, HC_UDP encoding = 11100000\n
* \verbatim * \verbatim
@ -804,26 +802,26 @@ uncompress_hdr_hc01(u16_t ip_len) {
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | LoWPAN HC1 Dsp| HC1 encoding | HC_UDP encod.| IPv6 Hop limit| * | LoWPAN HC1 Dsp| HC1 encoding | HC_UDP encod.| IPv6 Hop limit|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | src p.| dst p.| UDP checksum | L4 data... * | src p.| dst p.| UDP checksum | L4 data...
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* \endverbatim * \endverbatim
* *
* \param rime_destaddr L2 destination address, needed to compress the * \param rime_destaddr L2 destination address, needed to compress the
* IP destination field * IP destination field
*/ */
static void static void
compress_hdr_hc1(rimeaddr_t *rime_destaddr) compress_hdr_hc1(rimeaddr_t *rime_destaddr)
{ {
/* /*
* Check if all the assumptions for full compression * Check if all the assumptions for full compression
* are valid : * are valid :
*/ */
if(UIP_IP_BUF->vtc != 0x60 || if(UIP_IP_BUF->vtc != 0x60 ||
UIP_IP_BUF->tcflow != 0 || UIP_IP_BUF->tcflow != 0 ||
UIP_IP_BUF->flow != 0 || UIP_IP_BUF->flow != 0 ||
!uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr) || !uip_is_addr_link_local(&UIP_IP_BUF->srcipaddr) ||
!uip_is_addr_mac_addr_based(&UIP_IP_BUF->srcipaddr, &uip_lladdr) || !uip_is_addr_mac_addr_based(&UIP_IP_BUF->srcipaddr, &uip_lladdr) ||
!uip_is_addr_link_local(&UIP_IP_BUF->destipaddr) || !uip_is_addr_link_local(&UIP_IP_BUF->destipaddr) ||
!uip_is_addr_mac_addr_based(&UIP_IP_BUF->destipaddr, !uip_is_addr_mac_addr_based(&UIP_IP_BUF->destipaddr,
(uip_lladdr_t *)rime_destaddr) || (uip_lladdr_t *)rime_destaddr) ||
(UIP_IP_BUF->proto != UIP_PROTO_ICMP6 && (UIP_IP_BUF->proto != UIP_PROTO_ICMP6 &&
@ -832,9 +830,9 @@ compress_hdr_hc1(rimeaddr_t *rime_destaddr)
{ {
/* /*
* IPV6 DISPATCH * IPV6 DISPATCH
* Something cannot be compressed, use IPV6 DISPATCH, * Something cannot be compressed, use IPV6 DISPATCH,
* compress nothing, copy IPv6 header in rime buffer * compress nothing, copy IPv6 header in rime buffer
*/ */
*rime_ptr = SICSLOWPAN_DISPATCH_IPV6; *rime_ptr = SICSLOWPAN_DISPATCH_IPV6;
rime_hdr_len += SICSLOWPAN_IPV6_HDR_LEN; rime_hdr_len += SICSLOWPAN_IPV6_HDR_LEN;
memcpy(rime_ptr + rime_hdr_len, UIP_IP_BUF, UIP_IPH_LEN); memcpy(rime_ptr + rime_hdr_len, UIP_IP_BUF, UIP_IPH_LEN);
@ -847,7 +845,7 @@ compress_hdr_hc1(rimeaddr_t *rime_destaddr)
* All fields in the IP header but Hop Limit are elided * All fields in the IP header but Hop Limit are elided
* If next header is UDP, we compress UDP header using HC2 * If next header is UDP, we compress UDP header using HC2
*/ */
RIME_HC1_BUF->dispatch = SICSLOWPAN_DISPATCH_HC1; RIME_HC1_BUF->dispatch = SICSLOWPAN_DISPATCH_HC1;
uncomp_hdr_len += UIP_IPH_LEN; uncomp_hdr_len += UIP_IPH_LEN;
switch(UIP_IP_BUF->proto) { switch(UIP_IP_BUF->proto) {
case UIP_PROTO_ICMP6: case UIP_PROTO_ICMP6:
@ -866,7 +864,7 @@ compress_hdr_hc1(rimeaddr_t *rime_destaddr)
#endif /* UIP_CONF_TCP */ #endif /* UIP_CONF_TCP */
#if UIP_CONF_UDP #if UIP_CONF_UDP
case UIP_PROTO_UDP: case UIP_PROTO_UDP:
/* /*
* try to compress UDP header (we do only full compression). * try to compress UDP header (we do only full compression).
* This is feasible if both src and dest ports are between * This is feasible if both src and dest ports are between
* SICSLOWPAN_UDP_PORT_MIN and SICSLOWPAN_UDP_PORT_MIN + 15 * SICSLOWPAN_UDP_PORT_MIN and SICSLOWPAN_UDP_PORT_MIN + 15
@ -896,7 +894,7 @@ compress_hdr_hc1(rimeaddr_t *rime_destaddr)
} }
break; break;
#endif /*UIP_CONF_UDP*/ #endif /*UIP_CONF_UDP*/
} }
} }
return; return;
} }
@ -907,7 +905,7 @@ compress_hdr_hc1(rimeaddr_t *rime_destaddr)
* sicslowpan_buf * sicslowpan_buf
* *
* This function is called by the input function when the dispatch is * This function is called by the input function when the dispatch is
* HC1. * HC1.
* We %process the packet in the rime buffer, uncompress the header * We %process the packet in the rime buffer, uncompress the header
* fields, and copy the result in the sicslowpan buffer. * fields, and copy the result in the sicslowpan buffer.
* At the end of the decompression, rime_hdr_len and uncompressed_hdr_len * At the end of the decompression, rime_hdr_len and uncompressed_hdr_len
@ -926,10 +924,10 @@ uncompress_hdr_hc1(u16_t ip_len) {
/* src and dest ip addresses */ /* src and dest ip addresses */
uip_ip6addr(&SICSLOWPAN_IP_BUF->srcipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0); uip_ip6addr(&SICSLOWPAN_IP_BUF->srcipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0);
uip_netif_addr_autoconf_set(&SICSLOWPAN_IP_BUF->srcipaddr, uip_netif_addr_autoconf_set(&SICSLOWPAN_IP_BUF->srcipaddr,
(uip_lladdr_t *)rimebuf_addr(RIMEBUF_ADDR_SENDER)); (uip_lladdr_t *)rimebuf_addr(RIMEBUF_ADDR_SENDER));
uip_ip6addr(&SICSLOWPAN_IP_BUF->destipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0); uip_ip6addr(&SICSLOWPAN_IP_BUF->destipaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0);
uip_netif_addr_autoconf_set(&SICSLOWPAN_IP_BUF->destipaddr, uip_netif_addr_autoconf_set(&SICSLOWPAN_IP_BUF->destipaddr,
(uip_lladdr_t *)rimebuf_addr(RIMEBUF_ADDR_RECEIVER)); (uip_lladdr_t *)rimebuf_addr(RIMEBUF_ADDR_RECEIVER));
uncomp_hdr_len += UIP_IPH_LEN; uncomp_hdr_len += UIP_IPH_LEN;
@ -974,7 +972,7 @@ uncompress_hdr_hc1(u16_t ip_len) {
break; break;
#endif/* UIP_CONF_UDP */ #endif/* UIP_CONF_UDP */
default: default:
/* this shouldn't happen, drop */ /* this shouldn't happen, drop */
return; return;
} }
@ -1000,12 +998,12 @@ uncompress_hdr_hc1(u16_t ip_len) {
#if SICSLOWPAN_CONF_COMPRESSION == SICSLOWPAN_CONF_COMPRESSION_IPV6 #if SICSLOWPAN_CONF_COMPRESSION == SICSLOWPAN_CONF_COMPRESSION_IPV6
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
/** \name IPv6 dispatch "compression" function /** \name IPv6 dispatch "compression" function
* @{ */ * @{ */
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
/* \brief Packets "Compression" when only IPv6 dispatch is used /* \brief Packets "Compression" when only IPv6 dispatch is used
* *
* There is no compression in this case, all fields are sent * There is no compression in this case, all fields are sent
* inline. We just add the IPv6 dispatch byte before the packet. * inline. We just add the IPv6 dispatch byte before the packet.
* \verbatim * \verbatim
* 0 1 2 3 * 0 1 2 3
@ -1030,7 +1028,7 @@ compress_hdr_ipv6(rimeaddr_t *rime_destaddr) {
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
/** \name Input/output functions common to all compression schemes /** \name Input/output functions common to all compression schemes
* @{ */ * @{ */
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
/** /**
@ -1045,7 +1043,7 @@ send_packet(rimeaddr_t *dest)
/* Set the link layer destination address for the packet as a /* Set the link layer destination address for the packet as a
* rimebuf attribute. The MAC layer can access the destination * rimebuf attribute. The MAC layer can access the destination
* address with the function "rimebuf_addr(RIMEBUF_ADDR_RECEIVER); * address with the function "rimebuf_addr(RIMEBUF_ADDR_RECEIVER);
*/ */
rimebuf_set_addr(RIMEBUF_ADDR_RECEIVER, dest); rimebuf_set_addr(RIMEBUF_ADDR_RECEIVER, dest);
if(mac != NULL) { if(mac != NULL) {
@ -1077,7 +1075,7 @@ static u8_t
output(uip_lladdr_t *localdest) output(uip_lladdr_t *localdest)
{ {
/* The MAC address of the destination of the packet */ /* The MAC address of the destination of the packet */
rimeaddr_t dest; rimeaddr_t dest;
/* init */ /* init */
@ -1091,7 +1089,7 @@ output(uip_lladdr_t *localdest)
/* /*
* The destination address will be tagged to each outbound * The destination address will be tagged to each outbound
* packet. If the argument localdest is NULL, we are sending a * packet. If the argument localdest is NULL, we are sending a
* broadcast packet. * broadcast packet.
*/ */
if(localdest == NULL) { if(localdest == NULL) {
rimeaddr_copy(&dest, &rimeaddr_null); rimeaddr_copy(&dest, &rimeaddr_null);
@ -1117,8 +1115,8 @@ output(uip_lladdr_t *localdest)
#if SICSLOWPAN_CONF_FRAG #if SICSLOWPAN_CONF_FRAG
/* /*
* The outbound IPv6 packet is too large to fit into a single 15.4 * The outbound IPv6 packet is too large to fit into a single 15.4
* packet, so we fragment it into multiple packets and send them. * packet, so we fragment it into multiple packets and send them.
* The first fragment contains frag1 dispatch, then * The first fragment contains frag1 dispatch, then
* IPv6/HC1/HC01/HC_UDP dispatchs/headers. * IPv6/HC1/HC01/HC_UDP dispatchs/headers.
* The following fragments contain only the fragn dispatch. * The following fragments contain only the fragn dispatch.
*/ */
@ -1130,8 +1128,8 @@ output(uip_lladdr_t *localdest)
memmove(rime_ptr + SICSLOWPAN_FRAG1_HDR_LEN, rime_ptr, rime_hdr_len); memmove(rime_ptr + SICSLOWPAN_FRAG1_HDR_LEN, rime_ptr, rime_hdr_len);
/* /*
* FRAG1 dispatch + header * FRAG1 dispatch + header
* Note that the length is in units of 8 bytes * Note that the length is in units of 8 bytes
*/ */
RIME_FRAG_BUF->dispatch_size = RIME_FRAG_BUF->dispatch_size =
htons((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len); htons((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len);
@ -1150,8 +1148,8 @@ output(uip_lladdr_t *localdest)
processed_ip_len = rime_payload_len + uncomp_hdr_len; processed_ip_len = rime_payload_len + uncomp_hdr_len;
/* /*
* Create following fragments * Create following fragments
* Datagram tag is already in the buffer, we need to set the * Datagram tag is already in the buffer, we need to set the
* FRAGN dispatch and for each fragment, the offset * FRAGN dispatch and for each fragment, the offset
*/ */
rime_hdr_len = SICSLOWPAN_FRAGN_HDR_LEN; rime_hdr_len = SICSLOWPAN_FRAGN_HDR_LEN;
@ -1183,7 +1181,7 @@ output(uip_lladdr_t *localdest)
PRINTF("sicslowpan output: Packet too large to be sent without fragmentation support; dropping packet\n"); PRINTF("sicslowpan output: Packet too large to be sent without fragmentation support; dropping packet\n");
return 0; return 0;
#endif /* SICSLOWPAN_CONF_FRAG */ #endif /* SICSLOWPAN_CONF_FRAG */
} else { } else {
/* /*
* The packet does not need to be fragmented * The packet does not need to be fragmented
* copy "payload" and send * copy "payload" and send
@ -1197,7 +1195,7 @@ output(uip_lladdr_t *localdest)
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
/** \brief Process a received 6lowpan packet. /** \brief Process a received 6lowpan packet.
* \param r The MAC layer * \param r The MAC layer
* *
* The 6lowpan packet is put in rimebuf by the MAC. If its a frag1 or * The 6lowpan packet is put in rimebuf by the MAC. If its a frag1 or
@ -1207,7 +1205,7 @@ output(uip_lladdr_t *localdest)
* to uip_buf and the IP layer is called. * to uip_buf and the IP layer is called.
* *
* \note We do not check for overlapping sicslowpan fragments * \note We do not check for overlapping sicslowpan fragments
* (it is a SHALL in the RFC 4944 and should never happen) * (it is a SHALL in the RFC 4944 and should never happen)
*/ */
static void static void
input(const struct mac_driver *r) input(const struct mac_driver *r)
@ -1232,11 +1230,11 @@ input(const struct mac_driver *r)
/* if reassembly timed out, cancel it */ /* if reassembly timed out, cancel it */
if(timer_expired(&reass_timer)){ if(timer_expired(&reass_timer)){
sicslowpan_len = 0; sicslowpan_len = 0;
processed_ip_len = 0; processed_ip_len = 0;
} }
/* /*
* Since we don't support the mesh and broadcast header, the first header * Since we don't support the mesh and broadcast header, the first header
* we look for is the fragmentation header * we look for is the fragmentation header
*/ */
switch((ntohs(RIME_FRAG_BUF->dispatch_size) & 0xf800) >> 8) { switch((ntohs(RIME_FRAG_BUF->dispatch_size) & 0xf800) >> 8) {
case SICSLOWPAN_DISPATCH_FRAG1: case SICSLOWPAN_DISPATCH_FRAG1:
@ -1246,13 +1244,13 @@ input(const struct mac_driver *r)
frag_tag = ntohs(RIME_FRAG_BUF->tag); frag_tag = ntohs(RIME_FRAG_BUF->tag);
PRINTF("size %d, tag %d, offset %d)\n", PRINTF("size %d, tag %d, offset %d)\n",
frag_size, frag_tag, frag_offset); frag_size, frag_tag, frag_offset);
rime_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN; rime_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN;
break; break;
case SICSLOWPAN_DISPATCH_FRAGN: case SICSLOWPAN_DISPATCH_FRAGN:
/* /*
* set offset, tag, size * set offset, tag, size
* Offset is in units of 8 bytes * Offset is in units of 8 bytes
*/ */
PRINTF("sicslowpan input: FRAGN "); PRINTF("sicslowpan input: FRAGN ");
frag_offset = RIME_FRAG_BUF->offset; frag_offset = RIME_FRAG_BUF->offset;
@ -1268,10 +1266,10 @@ input(const struct mac_driver *r)
if(processed_ip_len > 0) { if(processed_ip_len > 0) {
/* reassembly is ongoing */ /* reassembly is ongoing */
if((frag_size > 0 && if((frag_size > 0 &&
(frag_size != sicslowpan_len || (frag_size != sicslowpan_len ||
reass_tag != frag_tag || reass_tag != frag_tag ||
!rimeaddr_cmp(&frag_sender, rimebuf_addr(RIMEBUF_ADDR_SENDER)))) || !rimeaddr_cmp(&frag_sender, rimebuf_addr(RIMEBUF_ADDR_SENDER)))) ||
frag_size == 0) { frag_size == 0) {
/* /*
* the packet is a fragment that does not belong to the packet * the packet is a fragment that does not belong to the packet
@ -1281,16 +1279,16 @@ input(const struct mac_driver *r)
return; return;
} }
} else { } else {
/* /*
* reassembly is off * reassembly is off
* start it if we received a fragment * start it if we received a fragment
*/ */
if(frag_size > 0){ if(frag_size > 0){
sicslowpan_len = frag_size; sicslowpan_len = frag_size;
reass_tag = frag_tag; reass_tag = frag_tag;
timer_set(&reass_timer, SICSLOWPAN_REASS_MAXAGE*CLOCK_SECOND); timer_set(&reass_timer, SICSLOWPAN_REASS_MAXAGE*CLOCK_SECOND);
PRINTF("sicslowpan input: INIT FRAGMENTATION (len %d, tag %d)\n", PRINTF("sicslowpan input: INIT FRAGMENTATION (len %d, tag %d)\n",
sicslowpan_len, reass_tag); sicslowpan_len, reass_tag);
rimeaddr_copy(&frag_sender, rimebuf_addr(RIMEBUF_ADDR_SENDER)); rimeaddr_copy(&frag_sender, rimebuf_addr(RIMEBUF_ADDR_SENDER));
} }
} }
@ -1337,14 +1335,14 @@ input(const struct mac_driver *r)
copypayload: copypayload:
#endif /*SICSLOWPAN_CONF_FRAG*/ #endif /*SICSLOWPAN_CONF_FRAG*/
/* /*
* copy "payload" from the rime buffer to the sicslowpan_buf * copy "payload" from the rime buffer to the sicslowpan_buf
* if this is a first fragment or not fragmented packet, * if this is a first fragment or not fragmented packet,
* we have already copied the compressed headers, uncomp_hdr_len * we have already copied the compressed headers, uncomp_hdr_len
* and rime_hdr_len are non 0, frag_offset is. * and rime_hdr_len are non 0, frag_offset is.
* If this is a subsequent fragment, this is the contrary. * If this is a subsequent fragment, this is the contrary.
*/ */
rime_payload_len = rimebuf_datalen() - rime_hdr_len; rime_payload_len = rimebuf_datalen() - rime_hdr_len;
memcpy((void *)SICSLOWPAN_IP_BUF + uncomp_hdr_len + (u16_t)(frag_offset << 3), rime_ptr + rime_hdr_len, rime_payload_len); memcpy((void *)SICSLOWPAN_IP_BUF + uncomp_hdr_len + (u16_t)(frag_offset << 3), rime_ptr + rime_hdr_len, rime_payload_len);
/* update processed_ip_len if fragment, sicslowpan_len otherwise */ /* update processed_ip_len if fragment, sicslowpan_len otherwise */
@ -1352,7 +1350,7 @@ input(const struct mac_driver *r)
if(frag_size > 0){ if(frag_size > 0){
if(processed_ip_len == 0) { if(processed_ip_len == 0) {
processed_ip_len += uncomp_hdr_len; processed_ip_len += uncomp_hdr_len;
} }
processed_ip_len += rime_payload_len; processed_ip_len += rime_payload_len;
} else { } else {
#endif /* SICSLOWPAN_CONF_FRAG */ #endif /* SICSLOWPAN_CONF_FRAG */
@ -1373,9 +1371,9 @@ input(const struct mac_driver *r)
processed_ip_len = 0; processed_ip_len = 0;
#endif /* SICSLOWPAN_CONF_FRAG */ #endif /* SICSLOWPAN_CONF_FRAG */
tcpip_input(); tcpip_input();
#if SICSLOWPAN_CONF_FRAG #if SICSLOWPAN_CONF_FRAG
} }
#endif /* SICSLOWPAN_CONF_FRAG */ #endif /* SICSLOWPAN_CONF_FRAG */
return; return;
} }
/** @} */ /** @} */
@ -1392,16 +1390,16 @@ sicslowpan_init(const struct mac_driver *m)
/* Set our input function as the receive function of the MAC. */ /* Set our input function as the receive function of the MAC. */
mac->set_receive_function(input); mac->set_receive_function(input);
/* /*
* Set out output function as the function to be called from uIP to * Set out output function as the function to be called from uIP to
* send a packet. * send a packet.
*/ */
tcpip_set_outputfunc(output); tcpip_set_outputfunc(output);
#if SICSLOWPAN_CONF_COMPRESSION == SICSLOWPAN_CONF_COMPRESSION_HC01 #if SICSLOWPAN_CONF_COMPRESSION == SICSLOWPAN_CONF_COMPRESSION_HC01
/* /*
* Initialize the address contexts * Initialize the address contexts
* Context 00 is link local context * Context 00 is link local context
* Other contexts are NULL at init * Other contexts are NULL at init
*/ */
addr_contexts[0].used = 1; addr_contexts[0].used = 1;

View File

@ -33,7 +33,7 @@
* *
* This file is part of the Contiki operating system. * This file is part of the Contiki operating system.
* *
* $Id: sicslowpan.h,v 1.1 2008/10/14 09:42:33 julienabeille Exp $ * $Id: sicslowpan.h,v 1.2 2008/10/14 12:26:18 adamdunkels Exp $
*/ */
/** /**
* \file * \file
@ -49,9 +49,8 @@
#ifndef __SICSLOWPAN_H__ #ifndef __SICSLOWPAN_H__
#define __SICSLOWPAN_H__ #define __SICSLOWPAN_H__
#include "net/uip.h" #include "net/uip.h"
#include "sicslowmac.h"
/** /**
* \name General sicslowpan defines * \name General sicslowpan defines
* @{ * @{
*/ */
@ -61,7 +60,7 @@
/** @} */ /** @} */
/** /**
* \name 6lowpan dispatchs * \name 6lowpan dispatchs
* @{ * @{
*/ */
@ -86,7 +85,7 @@
#define SICSLOWPAN_HC_UDP_ALL_C 0xE0 #define SICSLOWPAN_HC_UDP_ALL_C 0xE0
/** @} */ /** @} */
/** /**
* \name IPHC encoding * \name IPHC encoding
* @{ * @{
*/ */
@ -119,7 +118,7 @@
/** @} */ /** @} */
/** /**
* \name LOWPAN_UDP encoding (works together with IPHC) * \name LOWPAN_UDP encoding (works together with IPHC)
* @{ * @{
*/ */
@ -142,13 +141,13 @@
/** @} */ /** @} */
/** /**
* \brief The header for fragments * \brief The header for fragments
* \note We do not define different structuresfor FRAG1 * \note We do not define different structuresfor FRAG1
* and FRAGN headers, which are different. For FRAG1, the * and FRAGN headers, which are different. For FRAG1, the
* offset field is just not used * offset field is just not used
*/ */
struct sicslowpan_frag_hdr { struct sicslowpan_frag_hdr {
u16_t dispatch_size; u16_t dispatch_size;
u16_t tag; u16_t tag;
u8_t offset; u8_t offset;
}; };
@ -159,7 +158,7 @@ struct sicslowpan_frag_hdr {
* When all fields are compressed and HC_UDP is not used, * When all fields are compressed and HC_UDP is not used,
* we use this structure. If HC_UDP is used, the ttl is * we use this structure. If HC_UDP is used, the ttl is
* in another spot, and we use the sicslowpan_hc1_hc_udp * in another spot, and we use the sicslowpan_hc1_hc_udp
* structure * structure
*/ */
struct sicslowpan_hc1_hdr { struct sicslowpan_hc1_hdr {
u8_t dispatch; u8_t dispatch;
@ -232,9 +231,9 @@ struct sicslowpan_addr_context {
((*(a + 1) == 0x01) || (*(a + 1) == 0x02))) ((*(a + 1) == 0x01) || (*(a + 1) == 0x02)))
/** /**
* \brief check whether the 112-bit group-id of the * \brief check whether the 112-bit group-id of the
* multicast address is mapable to a 9-bit group-id * multicast address is mapable to a 9-bit group-id
* It is true if the group is the all nodes or all * It is true if the group is the all nodes or all
* routers group. * routers group.
*/ */
#define sicslowpan_is_mcast_addr_compressable(a) \ #define sicslowpan_is_mcast_addr_compressable(a) \

View File

@ -41,7 +41,7 @@
* *
* This file is part of the uIP TCP/IP stack. * This file is part of the uIP TCP/IP stack.
* *
* $Id: uip6.c,v 1.1 2008/10/14 09:42:33 julienabeille Exp $ * $Id: uip6.c,v 1.2 2008/10/14 12:26:18 adamdunkels Exp $
* *
*/ */
@ -71,12 +71,9 @@
* the packet back to the peer. * the packet back to the peer.
*/ */
//#include "net/uip.h"
//#include "net/uipopt.h"
#include "net/uip-icmp6.h" #include "net/uip-icmp6.h"
#include "net/uip-nd6.h" #include "net/uip-nd6.h"
#include "net/uip-netif.h" #include "net/uip-netif.h"
#include "raven-lcd.h"
#include <string.h> #include <string.h>
@ -124,8 +121,8 @@ uip_lladdr_t uip_lladdr = {{0x00,0x06,0x98,0x00,0x02,0x32}};
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/** /**
* \brief Type of the next header in IPv6 header or extension headers * \brief Type of the next header in IPv6 header or extension headers
* *
* Can be the next header field in the IPv6 header or in an extension header. * Can be the next header field in the IPv6 header or in an extension header.
* When doing fragment reassembly, we must change the value of the next header * When doing fragment reassembly, we must change the value of the next header
* field in the header before the fragmentation header, hence we need a pointer * field in the header before the fragmentation header, hence we need a pointer
* to this field. * to this field.
@ -134,7 +131,7 @@ u8_t *uip_next_hdr;
/** \brief bitmap we use to record which IPv6 headers we have already seen */ /** \brief bitmap we use to record which IPv6 headers we have already seen */
u8_t uip_ext_bitmap = 0; u8_t uip_ext_bitmap = 0;
/** /**
* \brief length of the extension headers read. updated each time we process * \brief length of the extension headers read. updated each time we process
* a header * a header
*/ */
u8_t uip_ext_len = 0; u8_t uip_ext_len = 0;
@ -167,17 +164,17 @@ u8_t uip_ext_opt_offset = 0;
*/ */
/** Packet buffer for incoming and outgoing packets */ /** Packet buffer for incoming and outgoing packets */
#ifndef UIP_CONF_EXTERNAL_BUFFER #ifndef UIP_CONF_EXTERNAL_BUFFER
u8_t uip_buf[UIP_BUFSIZE + 2]; u8_t uip_buf[UIP_BUFSIZE + 2];
#endif /* UIP_CONF_EXTERNAL_BUFFER */ #endif /* UIP_CONF_EXTERNAL_BUFFER */
/* The uip_appdata pointer points to application data. */ /* The uip_appdata pointer points to application data. */
void *uip_appdata; void *uip_appdata;
/* The uip_appdata pointer points to the application data which is to be sent*/ /* The uip_appdata pointer points to the application data which is to be sent*/
void *uip_sappdata; void *uip_sappdata;
#if UIP_URGDATA > 0 #if UIP_URGDATA > 0
/* The uip_urgdata pointer points to urgent data (out-of-band data), if present */ /* The uip_urgdata pointer points to urgent data (out-of-band data), if present */
void *uip_urgdata; void *uip_urgdata;
u16_t uip_urglen, uip_surglen; u16_t uip_urglen, uip_surglen;
#endif /* UIP_URGDATA > 0 */ #endif /* UIP_URGDATA > 0 */
@ -194,7 +191,7 @@ and the application program. */
u8_t uip_flags; u8_t uip_flags;
/* uip_conn always points to the current connection (set to NULL for UDP). */ /* uip_conn always points to the current connection (set to NULL for UDP). */
struct uip_conn *uip_conn; struct uip_conn *uip_conn;
/* Temporary variables. */ /* Temporary variables. */
#if (UIP_TCP || UIP_UDP) #if (UIP_TCP || UIP_UDP)
@ -203,7 +200,7 @@ static u8_t c;
#if UIP_ACTIVE_OPEN #if UIP_ACTIVE_OPEN
/* Keeps track of the last port used for a new connection. */ /* Keeps track of the last port used for a new connection. */
static u16_t lastport; static u16_t lastport;
#endif /* UIP_ACTIVE_OPEN */ #endif /* UIP_ACTIVE_OPEN */
/** @} */ /** @} */
@ -269,7 +266,7 @@ struct uip_icmp6_conn uip_icmp6_conns;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* Functions */ /* Functions */
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
#if (!UIP_ARCH_ADD32 && UIP_TCP) #if (!UIP_ARCH_ADD32 && UIP_TCP)
void void
uip_add32(u8_t *op32, u16_t op16) uip_add32(u8_t *op32, u16_t op16)
{ {
@ -588,7 +585,7 @@ static u8_t uip_reassflags;
/* /*
* See RFC 2460 for a description of fragmentation in IPv6 * See RFC 2460 for a description of fragmentation in IPv6
* A typical Ipv6 fragment * A typical Ipv6 fragment
* +------------------+--------+--------------+ * +------------------+--------+--------------+
* | Unfragmentable |Fragment| first | * | Unfragmentable |Fragment| first |
* | Part | Header | fragment | * | Part | Header | fragment |
@ -632,8 +629,8 @@ uip_reass(void)
*/ */
if(uip_ipaddr_cmp(&FBUF->srcipaddr, &UIP_IP_BUF->srcipaddr) && if(uip_ipaddr_cmp(&FBUF->srcipaddr, &UIP_IP_BUF->srcipaddr) &&
uip_ipaddr_cmp(&FBUF->destipaddr, &UIP_IP_BUF->destipaddr) && uip_ipaddr_cmp(&FBUF->destipaddr, &UIP_IP_BUF->destipaddr) &&
UIP_FRAG_BUF->id == uip_id) { UIP_FRAG_BUF->id == uip_id) {
len = uip_len - uip_ext_len - UIP_IPH_LEN - UIP_FRAGH_LEN; len = uip_len - uip_ext_len - UIP_IPH_LEN - UIP_FRAGH_LEN;
offset = (ntohs(UIP_FRAG_BUF->offsetresmore) & 0xfff8); offset = (ntohs(UIP_FRAG_BUF->offsetresmore) & 0xfff8);
/* in byte, originaly in multiple of 8 bytes*/ /* in byte, originaly in multiple of 8 bytes*/
PRINTF("len %d\n", len); PRINTF("len %d\n", len);
@ -665,8 +662,8 @@ uip_reass(void)
} }
/* If this fragment has the More Fragments flag set to zero, it is the /* If this fragment has the More Fragments flag set to zero, it is the
last fragment*/ last fragment*/
if((ntohs(UIP_FRAG_BUF->offsetresmore) & IP_MF) == 0) { if((ntohs(UIP_FRAG_BUF->offsetresmore) & IP_MF) == 0) {
uip_reassflags |= UIP_REASS_FLAG_LASTFRAG; uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
/*calculate the size of the entire packet*/ /*calculate the size of the entire packet*/
uip_reasslen = offset + len; uip_reasslen = offset + len;
@ -675,7 +672,7 @@ uip_reass(void)
/* If len is not a multiple of 8 octets and the M flag of that fragment /* If len is not a multiple of 8 octets and the M flag of that fragment
is 1, then that fragment must be discarded and an ICMP Parameter is 1, then that fragment must be discarded and an ICMP Parameter
Problem, Code 0, message should be sent to the source of the fragment, Problem, Code 0, message should be sent to the source of the fragment,
pointing to the Payload Length field of the fragment packet. */ pointing to the Payload Length field of the fragment packet. */
if(len % 8 != 0){ if(len % 8 != 0){
uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, 4); uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, 4);
uip_reassflags |= UIP_REASS_FLAG_ERROR_MSG; uip_reassflags |= UIP_REASS_FLAG_ERROR_MSG;
@ -714,7 +711,7 @@ uip_reass(void)
this by checking if we have the last fragment and if all bits this by checking if we have the last fragment and if all bits
in the bitmap are set. */ in the bitmap are set. */
if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) { if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) {
/* Check all bytes up to and including all but the last byte in /* Check all bytes up to and including all but the last byte in
the bitmap. */ the bitmap. */
for(i = 0; i < (uip_reasslen >> 6); ++i) { for(i = 0; i < (uip_reasslen >> 6); ++i) {
@ -801,8 +798,8 @@ uip_add_rcv_nxt(u16_t n)
*/ */
static u8_t static u8_t
ext_hdr_options_process() { ext_hdr_options_process() {
/* /*
* Length field in the extension header: length of th eheader in units of * Length field in the extension header: length of th eheader in units of
* 8 bytes, excluding the first 8 bytes * 8 bytes, excluding the first 8 bytes
* length field in an option : the length of data in the option * length field in an option : the length of data in the option
*/ */
@ -812,7 +809,7 @@ ext_hdr_options_process() {
/* /*
* for now we do not support any options except padding ones * for now we do not support any options except padding ones
* PAD1 does not make sense as the header must be 8bytes aligned, * PAD1 does not make sense as the header must be 8bytes aligned,
* hence we can only have * hence we can only have
*/ */
case UIP_EXT_HDR_OPT_PAD1: case UIP_EXT_HDR_OPT_PAD1:
PRINTF("Processing PAD1 option\n"); PRINTF("Processing PAD1 option\n");
@ -823,7 +820,7 @@ ext_hdr_options_process() {
uip_ext_opt_offset += UIP_EXT_HDR_OPT_PADN_BUF->opt_len + 2; uip_ext_opt_offset += UIP_EXT_HDR_OPT_PADN_BUF->opt_len + 2;
break; break;
default: default:
/* /*
* check the two highest order bits of the option * check the two highest order bits of the option
* - 00 skip over this option and continue processing the header. * - 00 skip over this option and continue processing the header.
* - 01 discard the packet. * - 01 discard the packet.
@ -845,9 +842,9 @@ ext_hdr_options_process() {
case 0xC0: case 0xC0:
if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) { if(uip_is_addr_mcast(&UIP_IP_BUF->destipaddr)) {
return 1; return 1;
} }
case 0x80: case 0x80:
uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION,
(u32_t)UIP_IPH_LEN + uip_ext_len + uip_ext_opt_offset); (u32_t)UIP_IPH_LEN + uip_ext_len + uip_ext_opt_offset);
return 2; return 2;
} }
@ -866,7 +863,7 @@ uip_process(u8_t flag)
{ {
#if UIP_TCP #if UIP_TCP
register struct uip_conn *uip_connr = uip_conn; register struct uip_conn *uip_connr = uip_conn;
#endif /* UIP_TCP */ #endif /* UIP_TCP */
#if UIP_UDP #if UIP_UDP
if(flag == UIP_UDP_SEND_CONN) { if(flag == UIP_UDP_SEND_CONN) {
goto udp_send; goto udp_send;
@ -885,7 +882,7 @@ uip_process(u8_t flag)
goto appsend; goto appsend;
} }
goto drop; goto drop;
#endif /* UIP_TCP */ #endif /* UIP_TCP */
/* Check if we were invoked because of the perodic timer fireing. */ /* Check if we were invoked because of the perodic timer fireing. */
} else if(flag == UIP_TIMER) { } else if(flag == UIP_TIMER) {
/* Reset the length variables. */ /* Reset the length variables. */
@ -918,7 +915,7 @@ uip_process(u8_t flag)
/* /*
* If the connection has outstanding data, we increase the * If the connection has outstanding data, we increase the
* connection's timer and see if it has reached the RTO value * connection's timer and see if it has reached the RTO value
* in which case we retransmit. * in which case we retransmit.
*/ */
if(uip_outstanding(uip_connr)) { if(uip_outstanding(uip_connr)) {
if(uip_connr->timer-- == 0) { if(uip_connr->timer-- == 0) {
@ -928,10 +925,10 @@ uip_process(u8_t flag)
uip_connr->nrtx == UIP_MAXSYNRTX)) { uip_connr->nrtx == UIP_MAXSYNRTX)) {
uip_connr->tcpstateflags = UIP_CLOSED; uip_connr->tcpstateflags = UIP_CLOSED;
/* /*
* We call UIP_APPCALL() with uip_flags set to * We call UIP_APPCALL() with uip_flags set to
* UIP_TIMEDOUT to inform the application that the * UIP_TIMEDOUT to inform the application that the
* connection has timed out. * connection has timed out.
*/ */
uip_flags = UIP_TIMEDOUT; uip_flags = UIP_TIMEDOUT;
UIP_APPCALL(); UIP_APPCALL();
@ -953,7 +950,7 @@ uip_process(u8_t flag)
* call upon the application so that it may prepare the * call upon the application so that it may prepare the
* data for the retransmit. In SYN_RCVD, we resend the * data for the retransmit. In SYN_RCVD, we resend the
* SYNACK that we sent earlier and in LAST_ACK we have to * SYNACK that we sent earlier and in LAST_ACK we have to
* retransmit our FINACK. * retransmit our FINACK.
*/ */
UIP_STAT(++uip_stat.tcp.rexmit); UIP_STAT(++uip_stat.tcp.rexmit);
switch(uip_connr->tcpstateflags & UIP_TS_MASK) { switch(uip_connr->tcpstateflags & UIP_TS_MASK) {
@ -989,7 +986,7 @@ uip_process(u8_t flag)
} else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) { } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) {
/* /*
* If there was no need for a retransmission, we poll the * If there was no need for a retransmission, we poll the
* application for new data. * application for new data.
*/ */
uip_flags = UIP_POLL; uip_flags = UIP_POLL;
UIP_APPCALL(); UIP_APPCALL();
@ -1033,7 +1030,7 @@ uip_process(u8_t flag)
* that the packet has been corrupted in transit. If the size of * that the packet has been corrupted in transit. If the size of
* uip_len is larger than the size reported in the IP packet header, * uip_len is larger than the size reported in the IP packet header,
* the packet has been padded and we set uip_len to the correct * the packet has been padded and we set uip_len to the correct
* value.. * value..
*/ */
if((UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] <= uip_len) { if((UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] <= uip_len) {
@ -1047,17 +1044,17 @@ uip_process(u8_t flag)
* problem as the length field in the IPv4 header * problem as the length field in the IPv4 header
* contains the length of the entire packet. But * contains the length of the entire packet. But
* for IPv6 we need to add the size of the IPv6 * for IPv6 we need to add the size of the IPv6
* header (40 bytes). * header (40 bytes).
*/ */
} else { } else {
UIP_LOG("ip: packet shorter than reported in IP header."); UIP_LOG("ip: packet shorter than reported in IP header.");
goto drop; goto drop;
} }
if(uip_is_addr_mcast(&UIP_IP_BUF->srcipaddr)){ if(uip_is_addr_mcast(&UIP_IP_BUF->srcipaddr)){
UIP_STAT(++uip_stat.ip.drop); UIP_STAT(++uip_stat.ip.drop);
goto drop; goto drop;
} }
if(!uip_netif_is_addr_my_unicast(&UIP_IP_BUF->destipaddr) && if(!uip_netif_is_addr_my_unicast(&UIP_IP_BUF->destipaddr) &&
@ -1069,7 +1066,7 @@ uip_process(u8_t flag)
/* /*
* Next header field processing. In IPv6, we can have extension headers, * Next header field processing. In IPv6, we can have extension headers,
* they are processed here * they are processed here
*/ */
uip_next_hdr = &UIP_IP_BUF->proto; uip_next_hdr = &UIP_IP_BUF->proto;
@ -1103,10 +1100,10 @@ uip_process(u8_t flag)
#endif /*UIP_CONF_IPV6_CHECKS*/ #endif /*UIP_CONF_IPV6_CHECKS*/
switch(ext_hdr_options_process()) { switch(ext_hdr_options_process()) {
case 0: case 0:
/*continue*/ /*continue*/
uip_next_hdr = &UIP_EXT_BUF->next; uip_next_hdr = &UIP_EXT_BUF->next;
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
break; break;
case 1: case 1:
/*silently discard*/ /*silently discard*/
goto drop; goto drop;
@ -1132,10 +1129,10 @@ uip_process(u8_t flag)
#endif /*UIP_CONF_IPV6_CHECKS*/ #endif /*UIP_CONF_IPV6_CHECKS*/
switch(ext_hdr_options_process()) { switch(ext_hdr_options_process()) {
case 0: case 0:
/*continue*/ /*continue*/
uip_next_hdr = &UIP_EXT_BUF->next; uip_next_hdr = &UIP_EXT_BUF->next;
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
break; break;
case 1: case 1:
/*silently discard*/ /*silently discard*/
goto drop; goto drop;
@ -1154,8 +1151,8 @@ uip_process(u8_t flag)
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_ROUTING; uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_ROUTING;
} }
#endif /*UIP_CONF_IPV6_CHECKS*/ #endif /*UIP_CONF_IPV6_CHECKS*/
/* /*
* Routing Header length field is in units of 8 bytes, excluding * Routing Header length field is in units of 8 bytes, excluding
* As per RFC2460 section 4.4, if routing type is unrecognized: * As per RFC2460 section 4.4, if routing type is unrecognized:
* if segments left = 0, ignore the header * if segments left = 0, ignore the header
* if segments left > 0, discard packet and send icmp error pointing * if segments left > 0, discard packet and send icmp error pointing
@ -1183,8 +1180,8 @@ uip_process(u8_t flag)
if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG){ if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG){
/* we are not done with reassembly, this is an error message */ /* we are not done with reassembly, this is an error message */
goto send; goto send;
} }
/*packet is reassembled, reset the next hdr to the beginning /*packet is reassembled, reset the next hdr to the beginning
of the IP header and restart the parsing of the reassembled pkt*/ of the IP header and restart the parsing of the reassembled pkt*/
PRINTF("Processing reassembled packet\n"); PRINTF("Processing reassembled packet\n");
uip_ext_len = 0; uip_ext_len = 0;
@ -1196,16 +1193,16 @@ uip_process(u8_t flag)
UIP_STAT(++uip_stat.ip.fragerr); UIP_STAT(++uip_stat.ip.fragerr);
UIP_LOG("ip: fragment dropped."); UIP_LOG("ip: fragment dropped.");
goto drop; goto drop;
#endif /* UIP_CONF_IPV6_REASSEMBLY */ #endif /* UIP_CONF_IPV6_REASSEMBLY */
case UIP_PROTO_NONE: case UIP_PROTO_NONE:
goto drop; goto drop;
default: default:
goto bad_hdr; goto bad_hdr;
} }
} }
bad_hdr: bad_hdr:
/* /*
* RFC 2460 send error message parameterr problem, code unrecognized * RFC 2460 send error message parameterr problem, code unrecognized
* next header, pointing to the next header field * next header, pointing to the next header field
*/ */
uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_NEXTHEADER, (u32_t)((void *)uip_next_hdr - (void *)UIP_IP_BUF)); uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_NEXTHEADER, (u32_t)((void *)uip_next_hdr - (void *)UIP_IP_BUF));
@ -1221,7 +1218,7 @@ uip_process(u8_t flag)
#if UIP_CONF_IPV6_CHECKS #if UIP_CONF_IPV6_CHECKS
/* Compute and check the ICMP header checksum */ /* Compute and check the ICMP header checksum */
if(uip_icmp6chksum() != 0xffff) { if(uip_icmp6chksum() != 0xffff) {
UIP_STAT(++uip_stat.icmp.drop); UIP_STAT(++uip_stat.icmp.drop);
UIP_STAT(++uip_stat.icmp.chkerr); UIP_STAT(++uip_stat.icmp.chkerr);
UIP_LOG("icmpv6: bad checksum."); UIP_LOG("icmpv6: bad checksum.");
@ -1235,7 +1232,7 @@ uip_process(u8_t flag)
* For echo request, we send echo reply * For echo request, we send echo reply
* For ND pkts, we call the appropriate function in uip-nd6-io.c * For ND pkts, we call the appropriate function in uip-nd6-io.c
* We do not treat Error messages for now * We do not treat Error messages for now
* If no pkt is to be sent as an answer to the incoming one, we * If no pkt is to be sent as an answer to the incoming one, we
* "goto drop". Else we just break; then at the after the "switch" * "goto drop". Else we just break; then at the after the "switch"
* we "goto send" * we "goto send"
*/ */