Merge pull request #416 from simonduq/contrib/sicslowpan

6LoWPAN fragment generation cleanup
This commit is contained in:
Simon Duquennoy 2018-05-14 13:19:16 +02:00 committed by GitHub
commit 644f2ac0f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 490 additions and 175 deletions

View File

@ -91,6 +91,11 @@
#define NBR_TABLE_CONF_MAX_NEIGHBORS 300
#endif /* NBR_TABLE_CONF_MAX_NEIGHBORS */
/* configure queues */
#ifndef QUEUEBUF_CONF_NUM
#define QUEUEBUF_CONF_NUM 64
#endif /* QUEUEBUF_CONF_NUM */
#ifndef UIP_CONF_IPV6_QUEUE_PKT
#define UIP_CONF_IPV6_QUEUE_PKT 1
#endif /* UIP_CONF_IPV6_QUEUE_PKT */

View File

@ -143,7 +143,7 @@ slip_radio_cmd_handler(const uint8_t *data, int len)
packetbuf_clear();
pos = packetutils_deserialize_atts(&data[3], len - 3);
if(pos < 0) {
LOG_ERR("slip-radio: illegal packet attributes\n");
LOG_ERR("illegal packet attributes\n");
return 1;
}
pos += 3;
@ -154,7 +154,7 @@ slip_radio_cmd_handler(const uint8_t *data, int len)
memcpy(packetbuf_dataptr(), &data[pos], len);
packetbuf_set_datalen(len);
LOG_DBG("slip-radio: sending %u (%d bytes)\n",
LOG_DBG("sending %u (%d bytes)\n",
data[2], packetbuf_datalen());
/* parse frame before sending to get addresses, etc. */

View File

@ -140,13 +140,13 @@
#define MAC_MAX_PAYLOAD (127 - 2)
#endif /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */
/** \brief Fixed size of a frame header. This value is
* used in case framer returns an error or if SICSLOWPAN_USE_FIXED_HDRLEN
* is defined.
*/
#ifndef SICSLOWPAN_FIXED_HDRLEN
#define SICSLOWPAN_FIXED_HDRLEN 21
#endif
/** \brief Maximum size of a frame header. This value is
* used in case framer returns an error */
#ifdef SICSLOWPAN_CONF_MAC_MAX_HEADER
#define MAC_MAX_HEADER SICSLOWPAN_CONF_MAC_MAX_HEADER
#else /* SICSLOWPAN_CONF_MAC_MAX_HEADER */
#define MAC_MAX_HEADER 21
#endif /* SICSLOWPAN_CONF_MAC_MAX_HEADER */
/* set this to zero if not compressing EXT_HDR - for backwards compatibility */
#ifdef SICSLOWPAN_CONF_COMPRESS_EXT_HDR
@ -336,8 +336,6 @@ store_fragment(uint8_t index, uint8_t offset)
frag_buf[i].index = index;
memcpy(frag_buf[i].data, packetbuf_ptr + packetbuf_hdr_len,
packetbuf_datalen() - packetbuf_hdr_len);
LOG_INFO("Fragsize: %d\n", frag_buf[i].len);
/* return the length of the stored fragment */
return frag_buf[i].len;
}
@ -371,7 +369,7 @@ add_fragment(uint16_t tag, uint16_t frag_size, uint8_t offset)
}
if(found < 0) {
LOG_WARN("*** Failed to store new fragment session - tag: %d\n", tag);
LOG_WARN("reassembly: failed to store new fragment session - tag: %d\n", tag);
return -1;
}
@ -398,7 +396,7 @@ add_fragment(uint16_t tag, uint16_t frag_size, uint8_t offset)
if(found < 0) {
/* no entry found for storing the new fragment */
LOG_WARN("*** Failed to store N-fragment - could not find session - tag: %d offset: %d\n", tag, offset);
LOG_WARN("reassembly: failed to store N-fragment - could not find session - tag: %d offset: %d\n", tag, offset);
return -1;
}
@ -413,7 +411,7 @@ add_fragment(uint16_t tag, uint16_t frag_size, uint8_t offset)
} else {
/* should we also clear all fragments since we failed to store
this fragment? */
LOG_WARN("*** Failed to store fragment - packet reassembly will fail tag:%d l\n", frag_info[i].tag);
LOG_WARN("reassembly: failed to store fragment - packet reassembly will fail tag:%d l\n", frag_info[i].tag);
return -1;
}
}
@ -610,7 +608,7 @@ uncompress_addr(uip_ipaddr_t *ipaddr, uint8_t const prefix[],
prefcount = prefcount == 15 ? 16 : prefcount;
postcount = postcount == 15 ? 16 : postcount;
LOG_INFO("Uncompressing %d + %d => ", prefcount, postcount);
LOG_DBG("uncompression: address %d %d", prefcount, postcount);
if(prefcount > 0) {
memcpy(ipaddr, prefix, prefcount);
@ -631,8 +629,8 @@ uncompress_addr(uip_ipaddr_t *ipaddr, uint8_t const prefix[],
uip_ds6_set_addr_iid(ipaddr, lladdr);
}
LOG_INFO_6ADDR(ipaddr);
LOG_INFO_("\n");
LOG_DBG_6ADDR(ipaddr);
LOG_DBG_("\n");
}
/*--------------------------------------------------------------------*/
@ -680,7 +678,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
if(LOG_DBG_ENABLED) {
uint16_t ndx;
LOG_DBG("before compression (%d): ", UIP_IP_BUF->len[1]);
LOG_DBG("compression: before (%d): ", UIP_IP_BUF->len[1]);
for(ndx = 0; ndx < UIP_IP_BUF->len[1] + 40; ndx++) {
uint8_t data = ((uint8_t *) (UIP_IP_BUF))[ndx];
LOG_DBG_("%02x", data);
@ -729,7 +727,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
if(addr_context_lookup_by_prefix(&UIP_IP_BUF->destipaddr) != NULL ||
addr_context_lookup_by_prefix(&UIP_IP_BUF->srcipaddr) != NULL) {
/* set context flag and increase hc06_ptr */
LOG_INFO("IPHC: compressing dest or src ipaddr - setting CID\n");
LOG_DBG("compression: dest or src ipaddr - setting CID\n");
iphc1 |= SICSLOWPAN_IPHC_CID;
hc06_ptr++;
}
@ -816,13 +814,13 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
/* source address - cannot be multicast */
if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) {
LOG_INFO("IPHC: compressing unspecified - setting SAC\n");
LOG_DBG("compression: addr unspecified - setting SAC\n");
iphc1 |= SICSLOWPAN_IPHC_SAC;
iphc1 |= SICSLOWPAN_IPHC_SAM_00;
} else if((context = addr_context_lookup_by_prefix(&UIP_IP_BUF->srcipaddr))
!= NULL) {
/* elide the prefix - indicate by CID and set context + SAC */
LOG_INFO("IPHC: compressing src with context - setting CID & SAC ctx: %d\n",
LOG_DBG("compression: src with context - setting CID & SAC ctx: %d\n",
context->number);
iphc1 |= SICSLOWPAN_IPHC_CID | SICSLOWPAN_IPHC_SAC;
PACKETBUF_IPHC_BUF[2] |= context->number << 4;
@ -905,9 +903,9 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
next_nhc = hc06_ptr; /* here we set the next header is compressed. */
ext_hdr_len = 0;
/* reserve the write place of this next header position */
LOG_INFO("Compressing first header: %d\n", *next_hdr);
LOG_DBG("compression: first header: %d\n", *next_hdr);
while(next_hdr != NULL && IS_COMPRESSABLE_PROTO(*next_hdr)) {
LOG_INFO("Compressing next header: %d\n", *next_hdr);
LOG_DBG("compression: next header: %d\n", *next_hdr);
int proto = -1; /* used for the specific ext hdr */
/* UDP and EXT header compression */
switch(*next_hdr) {
@ -926,7 +924,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_DESTO : proto;
/* Len is defined to be in octets from the length byte */
len = (ext_hdr->len << 3) + 8;
LOG_INFO("Handling next header: %d (len:%d)\n", *next_hdr, len);
LOG_DBG("compression: next header %d (len:%d)\n", *next_hdr, len);
/* pick up the next header */
next_hdr = &ext_hdr->next;
/* If the next header is not compressable we need to reserve the
@ -935,7 +933,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
if(!IS_COMPRESSABLE_PROTO(*next_hdr)) {
CHECK_BUFFER_SPACE(1);
hc06_ptr++;
LOG_INFO("Keeping the next header in this ext hdr: %d\n",
LOG_DBG("compression: keeping the next header in this ext hdr: %d\n",
ext_hdr->next);
}
/* copy the ext-hdr into the hc06 buffer */
@ -961,14 +959,14 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
/* allocate a byte for the next header posision as UDP has no next */
hc06_ptr++;
udp_buf = UIP_UDP_BUF(ext_hdr_len);
LOG_INFO("IPHC: Uncompressed UDP ports on send side: %x, %x\n",
LOG_DBG("compression: inlined UDP ports on send side: %x, %x\n",
UIP_HTONS(udp_buf->srcport), UIP_HTONS(udp_buf->destport));
/* Mask out the last 4 bits can be used as a mask */
if(((UIP_HTONS(udp_buf->srcport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN) &&
((UIP_HTONS(udp_buf->destport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN)) {
/* we can compress 12 bits of both source and dest */
*next_nhc = SICSLOWPAN_NHC_UDP_CS_P_11;
LOG_INFO("IPHC: remove 12 b of both source & dest with prefix 0xFOB\n");
LOG_DBG("IPHC: remove 12 b of both source & dest with prefix 0xFOB\n");
CHECK_BUFFER_SPACE(1);
*hc06_ptr =
(uint8_t)((UIP_HTONS(udp_buf->srcport) -
@ -979,7 +977,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
} else if((UIP_HTONS(udp_buf->destport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
/* we can compress 8 bits of dest, leave source. */
*next_nhc = SICSLOWPAN_NHC_UDP_CS_P_01;
LOG_INFO("IPHC: leave source, remove 8 bits of dest with prefix 0xF0\n");
LOG_DBG("IPHC: leave source, remove 8 bits of dest with prefix 0xF0\n");
CHECK_BUFFER_SPACE(3);
memcpy(hc06_ptr, &udp_buf->srcport, 2);
*(hc06_ptr + 2) =
@ -989,7 +987,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
} else if((UIP_HTONS(udp_buf->srcport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
/* we can compress 8 bits of src, leave dest. Copy compressed port */
*next_nhc = SICSLOWPAN_NHC_UDP_CS_P_10;
LOG_INFO("IPHC: remove 8 bits of source with prefix 0xF0, leave dest. hch: %i\n", *next_nhc);
LOG_DBG("IPHC: remove 8 bits of source with prefix 0xF0, leave dest. hch: %i\n", *next_nhc);
CHECK_BUFFER_SPACE(3);
*hc06_ptr =
(uint8_t)((UIP_HTONS(udp_buf->srcport) -
@ -999,7 +997,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
} else {
/* we cannot compress. Copy uncompressed ports, full checksum */
*next_nhc = SICSLOWPAN_NHC_UDP_CS_P_00;
LOG_INFO("IPHC: cannot compress UDP headers\n");
LOG_DBG("IPHC: cannot compress UDP headers\n");
CHECK_BUFFER_SPACE(4);
memcpy(hc06_ptr, &udp_buf->srcport, 4);
hc06_ptr += 4;
@ -1009,17 +1007,17 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
memcpy(hc06_ptr, &udp_buf->udpchksum, 2);
hc06_ptr += 2;
uncomp_hdr_len += UIP_UDPH_LEN;
/* this is the final header... */
/* this is the final header. */
next_hdr = NULL;
break;
default:
LOG_ERR("IPHC: could not handle compression of header");
LOG_ERR("compression: could not handle compression of header");
}
}
if(next_hdr != NULL) {
/* Last header could not be compressed - we assume that this is then OK!*/
/* as the last EXT_HDR should be "uncompressed" and have the next there */
LOG_INFO("IPHC: last header could is not compressed: %d\n", *next_hdr);
LOG_DBG("compression: last header could is not compressed: %d\n", *next_hdr);
}
/* before the packetbuf_hdr_len operation */
PACKETBUF_IPHC_BUF[0] = iphc0;
@ -1027,7 +1025,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
if(LOG_DBG_ENABLED) {
uint16_t ndx;
LOG_DBG("after compression %d: ", (int)(hc06_ptr - packetbuf_ptr));
LOG_DBG("compression: after (%d): ", (int)(hc06_ptr - packetbuf_ptr));
for(ndx = 0; ndx < hc06_ptr - packetbuf_ptr; ndx++) {
uint8_t data = ((uint8_t *) packetbuf_ptr)[ndx];
LOG_DBG_("%02x", data);
@ -1074,7 +1072,7 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
/* another if the CID flag is set */
if(iphc1 & SICSLOWPAN_IPHC_CID) {
LOG_INFO("IPHC: CID flag set - increase header with one\n");
LOG_DBG("uncompression: CID flag set - increase header with one\n");
hc06_ptr++;
}
@ -1122,7 +1120,7 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) {
/* Next header is carried inline */
SICSLOWPAN_IP_BUF(buf)->proto = *hc06_ptr;
LOG_INFO("IPHC: next header inline: %d\n", SICSLOWPAN_IP_BUF(buf)->proto);
LOG_DBG("uncompression: next header inline: %d\n", SICSLOWPAN_IP_BUF(buf)->proto);
hc06_ptr += 1;
}
@ -1146,7 +1144,7 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
if (tmp != 0) {
context = addr_context_lookup_by_number(sci);
if(context == NULL) {
LOG_ERR("uncompress_hdr: error context not found\n");
LOG_ERR("uncompression: error context not found\n");
return;
}
}
@ -1193,7 +1191,7 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
/* all valid cases below need the context! */
if(context == NULL) {
LOG_ERR("uncompress_hdr: error context not found\n");
LOG_ERR("uncompression: error context not found\n");
return;
}
uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, context->prefix,
@ -1228,12 +1226,12 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
if(!nh) {
next = *hc06_ptr;
hc06_ptr++;
LOG_INFO("Next header is not compressed... next: %d\n", next);
LOG_DBG("uncompression: next header is inlined. Next: %d\n", next);
}
len = *hc06_ptr;
hc06_ptr++;
LOG_INFO("IPHC: Found extension-header id=%d next=%d len=%d\n", eid, next, len);
LOG_DBG("uncompression: found ext header id: %d next: %d len: %d\n", eid, next, len);
switch(eid) {
case SICSLOWPAN_NHC_ETX_HDR_HBHO:
proto = UIP_PROTO_HBHO;
@ -1248,7 +1246,7 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
proto = UIP_PROTO_DESTO;
break;
default:
LOG_INFO("IPHC: error unsupported extension-header\n");
LOG_DBG("uncompression: error unsupported ext header\n");
return;
}
*last_nextheader = proto;
@ -1263,7 +1261,7 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
ip_payload += (exthdr->len + 1) * 8;
ext_hdr_len += (exthdr->len + 1) * 8;
LOG_INFO("Uncompressed EXT hdr: %d len:%d exhdrlen:%d (calc: %d)\n",
LOG_DBG("uncompression: %d len: %d exhdrlen: %d (calc: %d)\n",
proto, len, exthdr->len, (exthdr->len + 1) * 8);
}
@ -1274,13 +1272,13 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
uint8_t checksum_compressed;
*last_nextheader = UIP_PROTO_UDP;
checksum_compressed = *hc06_ptr & SICSLOWPAN_NHC_UDP_CHECKSUMC;
LOG_INFO("IPHC: Incoming header value: %i\n", *hc06_ptr);
LOG_DBG("uncompression: incoming header value: %i\n", *hc06_ptr);
switch(*hc06_ptr & SICSLOWPAN_NHC_UDP_CS_P_11) {
case SICSLOWPAN_NHC_UDP_CS_P_00:
/* 1 byte for NHC, 4 byte for ports, 2 bytes chksum */
memcpy(&udp_buf->srcport, hc06_ptr + 1, 2);
memcpy(&udp_buf->destport, hc06_ptr + 3, 2);
LOG_INFO("IPHC: Uncompressed UDP ports (ptr+5): %x, %x\n",
LOG_DBG("uncompression: UDP ports (ptr+5): %x, %x\n",
UIP_HTONS(udp_buf->srcport),
UIP_HTONS(udp_buf->destport));
hc06_ptr += 5;
@ -1288,21 +1286,21 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
case SICSLOWPAN_NHC_UDP_CS_P_01:
/* 1 byte for NHC + source 16bit inline, dest = 0xF0 + 8 bit inline */
LOG_INFO("IPHC: Decompressing destination\n");
LOG_DBG("uncompression: destination address\n");
memcpy(&udp_buf->srcport, hc06_ptr + 1, 2);
udp_buf->destport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(hc06_ptr + 3)));
LOG_INFO("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n",
LOG_DBG("uncompression: UDP ports (ptr+4): %x, %x\n",
UIP_HTONS(udp_buf->srcport), UIP_HTONS(udp_buf->destport));
hc06_ptr += 4;
break;
case SICSLOWPAN_NHC_UDP_CS_P_10:
/* 1 byte for NHC + source = 0xF0 + 8bit inline, dest = 16 bit inline*/
LOG_INFO("IPHC: Decompressing source\n");
LOG_DBG("uncompression: source address\n");
udp_buf->srcport = UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN +
(*(hc06_ptr + 1)));
memcpy(&udp_buf->destport, hc06_ptr + 2, 2);
LOG_INFO("IPHC: Uncompressed UDP ports (ptr+4): %x, %x\n",
LOG_DBG("uncompression: UDP ports (ptr+4): %x, %x\n",
UIP_HTONS(udp_buf->srcport), UIP_HTONS(udp_buf->destport));
hc06_ptr += 4;
break;
@ -1313,27 +1311,27 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
(*(hc06_ptr + 1) >> 4));
udp_buf->destport = UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
((*(hc06_ptr + 1)) & 0x0F));
LOG_INFO("IPHC: Uncompressed UDP ports (ptr+2): %x, %x\n",
LOG_DBG("uncompression: UDP ports (ptr+2): %x, %x\n",
UIP_HTONS(udp_buf->srcport), UIP_HTONS(udp_buf->destport));
hc06_ptr += 2;
break;
default:
LOG_INFO("sicslowpan uncompress_hdr: error unsupported UDP compression\n");
LOG_DBG("uncompression: error unsupported UDP compression\n");
return;
}
if(!checksum_compressed) { /* has_checksum, default */
memcpy(&udp_buf->udpchksum, hc06_ptr, 2);
hc06_ptr += 2;
LOG_INFO("IPHC: sicslowpan uncompress_hdr: checksum included\n");
LOG_DBG("uncompression: checksum included\n");
} else {
LOG_INFO("IPHC: sicslowpan uncompress_hdr: checksum *NOT* included\n");
LOG_DBG("uncompression: checksum *NOT* included\n");
}
/* length field in UDP header (8 byte header + payload) */
udp_len = 8 + packetbuf_datalen() - (hc06_ptr - packetbuf_ptr);
udp_buf->udplen = UIP_HTONS(ip_len == 0 ? udp_len :
ip_len - UIP_IPH_LEN - ext_hdr_len);
LOG_INFO("Setting UDP length: %u (ext: %u) ip_len: %d udp_len:%d\n",
LOG_DBG("uncompression: UDP length: %u (ext: %u) ip_len: %d udp_len: %d\n",
UIP_HTONS(udp_buf->udplen), ext_hdr_len, ip_len, udp_len);
uncomp_hdr_len += UIP_UDPH_LEN;
@ -1344,7 +1342,7 @@ uncompress_hdr_iphc(uint8_t *buf, uint16_t ip_len)
/* IP length field. */
if(ip_len == 0) {
int len = packetbuf_datalen() - packetbuf_hdr_len + uncomp_hdr_len - UIP_IPH_LEN;
LOG_INFO("IP payload length: %d. %u - %u + %u - %u\n", len,
LOG_DBG("uncompression: IP payload length: %d. %u - %u + %u - %u\n", len,
packetbuf_datalen(), packetbuf_hdr_len, uncomp_hdr_len, UIP_IPH_LEN);
/* This is not a fragmented packet */
@ -1495,6 +1493,48 @@ send_packet(linkaddr_t *dest)
watchdog know that we are still alive. */
watchdog_periodic();
}
#if SICSLOWPAN_CONF_FRAG
/*--------------------------------------------------------------------*/
/**
* \brief This function is called by the 6lowpan code to copy a fragment's
* payload from uIP and send it down the stack.
* \param uip_offset the offset in the uIP buffer where to copy the payload from
* \param dest the link layer destination address of the packet
* \return 1 if success, 0 otherwise
*/
static int
fragment_copy_payload_and_send(uint16_t uip_offset, linkaddr_t *dest) {
struct queuebuf *q;
/* Now copy fragment payload from uip_buf */
memcpy(packetbuf_ptr + packetbuf_hdr_len,
(uint8_t *)UIP_IP_BUF + uip_offset, packetbuf_payload_len);
packetbuf_set_datalen(packetbuf_payload_len + packetbuf_hdr_len);
/* Backup packetbuf to queuebuf. Enables preserving attributes for all framgnets */
q = queuebuf_new_from_packetbuf();
if(q == NULL) {
LOG_WARN("output: could not allocate queuebuf, dropping fragment\n");
return 0;
}
/* Send fragment */
send_packet(dest);
/* Restore packetbuf from queuebuf */
queuebuf_to_packetbuf(q);
queuebuf_free(q);
/* Check tx result. */
if((last_tx_status == MAC_TX_COLLISION) ||
(last_tx_status == MAC_TX_ERR) ||
(last_tx_status == MAC_TX_ERR_FATAL)) {
LOG_ERR("output: error in fragment tx, dropping subsequent fragments.\n");
return 0;
}
return 1;
}
#endif /* SICSLOWPAN_CONF_FRAG */
/*--------------------------------------------------------------------*/
/** \brief Take an IP packet and format it to be sent on an 802.15.4
* network using 6lowpan.
@ -1509,6 +1549,8 @@ static uint8_t
output(const linkaddr_t *localdest)
{
int framer_hdrlen;
int max_payload;
int frag_needed;
/* The MAC address of the destination of the packet */
linkaddr_t dest;
@ -1538,23 +1580,19 @@ output(const linkaddr_t *localdest)
linkaddr_copy(&dest, localdest);
}
LOG_INFO("output: sending packet len %d\n", uip_len);
LOG_INFO("output: sending IPv6 packet with len %d\n", uip_len);
/* copy over the retransmission count from uipbuf attributes */
packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS,
uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS));
/* Calculate NETSTACK_FRAMER's header length, that will be added in the NETSTACK_MAC */
#ifndef SICSLOWPAN_USE_FIXED_HDRLEN
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest);
framer_hdrlen = NETSTACK_FRAMER.length();
if(framer_hdrlen < 0) {
/* Framing failed, we assume the maximum header length */
framer_hdrlen = SICSLOWPAN_FIXED_HDRLEN;
framer_hdrlen = MAC_MAX_HEADER;
}
#else /* USE_FRAMER_HDRLEN */
framer_hdrlen = SICSLOWPAN_FIXED_HDRLEN;
#endif /* USE_FRAMER_HDRLEN */
mac_max_payload = MAC_MAX_PAYLOAD - framer_hdrlen;
@ -1576,131 +1614,134 @@ output(const linkaddr_t *localdest)
return 0;
}
#endif /* SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC */
LOG_INFO("output: header of len %d\n", packetbuf_hdr_len);
if((int)uip_len - (int)uncomp_hdr_len > mac_max_payload - (int)packetbuf_hdr_len) {
/* Calculate NETSTACK_FRAMER's header length, that will be added in the NETSTACK_MAC.
* We calculate it here only to make a better decision of whether the outgoing packet
* needs to be fragmented or not. */
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest);
framer_hdrlen = NETSTACK_FRAMER.length();
if(framer_hdrlen < 0) {
/* Framing failed, we assume the maximum header length */
framer_hdrlen = MAC_MAX_HEADER;
}
max_payload = MAC_MAX_PAYLOAD - framer_hdrlen;
frag_needed = (int)uip_len - (int)uncomp_hdr_len + (int)packetbuf_hdr_len > max_payload;
LOG_INFO("output: header len %d -> %d, total len %d -> %d, MAC max payload %d, frag_needed %d\n",
uncomp_hdr_len, packetbuf_hdr_len,
uip_len, uip_len - uncomp_hdr_len + packetbuf_hdr_len,
max_payload, frag_needed);
if(frag_needed) {
#if SICSLOWPAN_CONF_FRAG
/* Number of bytes processed. */
uint16_t processed_ip_out_len;
struct queuebuf *q;
uint16_t frag_tag;
int curr_frag = 0;
/*
* 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.
* The first fragment contains frag1 dispatch, then
* IPv6/IPHC/HC_UDP dispatchs/headers.
* The following fragments contain only the fragn dispatch.
* The first fragment contains frag1 dispatch, then IPv6/IPHC/HC_UDP
* dispatchs/headers and IPv6 payload (with len multiple of 8 bytes).
* The subsequent fragments contain the FRAGN dispatch and more of the
* IPv6 payload (still multiple of 8 bytes, except for the last fragment)
*/
int estimated_fragments = ((int)uip_len) / (mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN) + 1;
/* Total IPv6 payload */
int total_payload = (uip_len - uncomp_hdr_len);
/* IPv6 payload that goes to first fragment */
int frag1_payload = (max_payload - packetbuf_hdr_len - SICSLOWPAN_FRAG1_HDR_LEN) & 0xfffffff8;
/* max IPv6 payload in each FRAGN. Must be multiple of 8 bytes */
int fragn_max_payload = (max_payload - SICSLOWPAN_FRAGN_HDR_LEN) & 0xfffffff8;
/* max IPv6 payload in the last fragment. Needs not be multiple of 8 bytes */
int last_fragn_max_payload = max_payload - SICSLOWPAN_FRAGN_HDR_LEN;
/* sum of all IPv6 payload that goes to non-first and non-last fragments */
int middle_fragn_total_payload = MAX(total_payload - frag1_payload - last_fragn_max_payload, 0);
/* Ceiling of: 2 + middle_fragn_total_payload / fragn_max_payload */
int fragment_count = 2;
if(middle_fragn_total_payload > 0) {
fragment_count += 1 + (middle_fragn_total_payload - 1) / fragn_max_payload;
}
int freebuf = queuebuf_numfree() - 1;
LOG_INFO("uip_len: %d, fragments: %d, free bufs: %d\n", uip_len, estimated_fragments, freebuf);
if(freebuf < estimated_fragments) {
LOG_WARN("Dropping packet, not enough free bufs\n");
LOG_INFO("output: fragmentation needed, fragments: %u, free queuebufs: %u\n",
fragment_count, freebuf);
if(freebuf < fragment_count) {
LOG_WARN("output: dropping packet, not enough free bufs (needed: %u, free: %u)\n",
fragment_count, freebuf);
return 0;
}
LOG_INFO("Fragmentation sending packet len %d\n", uip_len);
/* Create 1st Fragment */
LOG_INFO("output: 1st fragment ");
/* Reset last tx status to ok in case the fragment transmissions are deferred */
last_tx_status = MAC_TX_OK;
/* move IPHC/IPv6 header */
memmove(packetbuf_ptr + SICSLOWPAN_FRAG1_HDR_LEN, packetbuf_ptr, packetbuf_hdr_len);
/*
* FRAG1 dispatch + header
* Note that the length is in units of 8 bytes
*/
SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len));
frag_tag = my_tag++;
SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG, frag_tag);
/* Copy payload and send */
packetbuf_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN;
packetbuf_payload_len = (mac_max_payload - packetbuf_hdr_len) & 0xfffffff8;
LOG_INFO_("(len %d, tag %d)\n", packetbuf_payload_len, frag_tag);
if(packetbuf_payload_len < 0) {
if(frag1_payload < 0) {
/* The current implementation requires that all headers fit in the first
* fragment. Here is a corner case where the header did fit packetbuf
* but do no longer fit after truncating for a length multiple of 8. */
LOG_WARN("compressed header does not fit first fragment\n");
LOG_WARN("output: compressed header does not fit first fragment\n");
return 0;
}
memcpy(packetbuf_ptr + packetbuf_hdr_len,
(uint8_t *)UIP_IP_BUF + uncomp_hdr_len, packetbuf_payload_len);
packetbuf_set_datalen(packetbuf_payload_len + packetbuf_hdr_len);
q = queuebuf_new_from_packetbuf();
if(q == NULL) {
LOG_WARN("could not allocate queuebuf for first fragment, dropping packet\n");
return 0;
}
send_packet(&dest);
queuebuf_to_packetbuf(q);
queuebuf_free(q);
q = NULL;
/* Reset last tx status -- MAC layers most often call packet_sent asynchrously */
last_tx_status = MAC_TX_OK;
/* Update fragment tag */
frag_tag = my_tag++;
/* Check tx result. */
if((last_tx_status == MAC_TX_COLLISION) ||
(last_tx_status == MAC_TX_ERR) ||
(last_tx_status == MAC_TX_ERR_FATAL)) {
LOG_ERR("error in fragment tx, dropping subsequent fragments.\n");
/* Move IPHC/IPv6 header to make room for FRAG1 header */
memmove(packetbuf_ptr + SICSLOWPAN_FRAG1_HDR_LEN, packetbuf_ptr, packetbuf_hdr_len);
packetbuf_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN;
/* Set FRAG1 header */
SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len));
SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG, frag_tag);
/* Set frag1 payload len. Was already caulcated earlier as frag1_payload */
packetbuf_payload_len = frag1_payload;
/* Copy payload from uIP and send fragment */
/* Send fragment */
LOG_INFO("output: fragment %d/%d (tag %d, payload %d)\n",
curr_frag + 1, fragment_count,
frag_tag, packetbuf_payload_len);
if(fragment_copy_payload_and_send(uncomp_hdr_len, &dest) == 0) {
return 0;
}
/* set processed_ip_out_len to what we already sent from the IP payload*/
processed_ip_out_len = packetbuf_payload_len + uncomp_hdr_len;
/* Now prepare for subsequent fragments. */
/*
* Create following fragments
* Datagram tag is already in the buffer, we need to set the
* FRAGN dispatch and for each fragment, the offset
*/
/* FRAGN header: tag was already set at FRAG1. Now set dispatch for all FRAGN */
packetbuf_hdr_len = SICSLOWPAN_FRAGN_HDR_LEN;
/* PACKETBUF_FRAG_BUF->dispatch_size = */
/* uip_htons((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len); */
SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len));
packetbuf_payload_len = (mac_max_payload - packetbuf_hdr_len) & 0xfffffff8;
/* Keep track of the total length of data sent */
processed_ip_out_len = uncomp_hdr_len + packetbuf_payload_len;
/* Create and send subsequent fragments. */
while(processed_ip_out_len < uip_len) {
LOG_INFO("output: fragment ");
curr_frag++;
/* FRAGN header: set offset for this fragment */
PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3;
/* Copy payload and send */
if(uip_len - processed_ip_out_len < packetbuf_payload_len) {
/* Calculate fragment len */
if(uip_len - processed_ip_out_len > last_fragn_max_payload) {
/* Not last fragment, send max FRAGN payload */
packetbuf_payload_len = fragn_max_payload;
} else {
/* last fragment */
packetbuf_payload_len = uip_len - processed_ip_out_len;
}
LOG_INFO_("(offset %d, len %d, tag %d)\n",
processed_ip_out_len >> 3, packetbuf_payload_len, frag_tag);
memcpy(packetbuf_ptr + packetbuf_hdr_len,
(uint8_t *)UIP_IP_BUF + processed_ip_out_len, packetbuf_payload_len);
packetbuf_set_datalen(packetbuf_payload_len + packetbuf_hdr_len);
q = queuebuf_new_from_packetbuf();
if(q == NULL) {
LOG_WARN("could not allocate queuebuf, dropping fragment\n");
return 0;
}
send_packet(&dest);
queuebuf_to_packetbuf(q);
queuebuf_free(q);
q = NULL;
processed_ip_out_len += packetbuf_payload_len;
/* Check tx result. */
if((last_tx_status == MAC_TX_COLLISION) ||
(last_tx_status == MAC_TX_ERR) ||
(last_tx_status == MAC_TX_ERR_FATAL)) {
LOG_ERR("error in fragment tx, dropping subsequent fragments.\n");
/* Copy payload from uIP and send fragment */
/* Send fragment */
LOG_INFO("output: fragment %d/%d (tag %d, payload %d, offset %d)\n",
curr_frag + 1, fragment_count,
frag_tag, packetbuf_payload_len, processed_ip_out_len);
if(fragment_copy_payload_and_send(processed_ip_out_len, &dest) == 0) {
return 0;
}
processed_ip_out_len += packetbuf_payload_len;
}
#else /* SICSLOWPAN_CONF_FRAG */
LOG_ERR("output: Packet too large to be sent without fragmentation support; dropping packet\n");
@ -1761,7 +1802,7 @@ input(void)
packetbuf_ptr = packetbuf_dataptr();
if(packetbuf_datalen() == 0) {
LOG_WARN("empty packet\n");
LOG_WARN("input: empty packet\n");
return;
}
@ -1780,20 +1821,21 @@ input(void)
*/
switch((GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) >> 8) & SICSLOWPAN_DISPATCH_FRAG_MASK) {
case SICSLOWPAN_DISPATCH_FRAG1:
LOG_INFO("input: FRAG1 ");
frag_offset = 0;
frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
LOG_INFO_ ("size %d, tag %d, offset %d)\n",
frag_size, frag_tag, frag_offset);
packetbuf_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN;
first_fragment = 1;
is_fragment = 1;
LOG_INFO("input: received first element of a fragmented packet (tag %d, len %d)\n",
frag_tag, frag_size);
/* Add the fragment to the fragmentation context */
frag_context = add_fragment(frag_tag, frag_size, frag_offset);
if(frag_context == -1) {
LOG_ERR("input: failed to allocate new reassembly context\n");
return;
}
@ -1805,24 +1847,17 @@ input(void)
* set offset, tag, size
* Offset is in units of 8 bytes
*/
LOG_INFO("input: FRAGN ");
frag_offset = PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET];
frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
LOG_INFO_("size %d, tag %d, offset %d)\n",
frag_size, frag_tag, frag_offset);
packetbuf_hdr_len += SICSLOWPAN_FRAGN_HDR_LEN;
/* If this is the last fragment, we may shave off any extrenous
bytes at the end. We must be liberal in what we accept. */
LOG_INFO_("last_fragment?: packetbuf_payload_len %d frag_size %d\n",
packetbuf_datalen() - packetbuf_hdr_len, frag_size);
/* Add the fragment to the fragmentation context (this will also
copy the payload) */
frag_context = add_fragment(frag_tag, frag_size, frag_offset);
if(frag_context == -1) {
LOG_ERR("input: reassembly context not found (tag %d)\n", frag_tag);
return;
}
@ -1858,10 +1893,10 @@ input(void)
/* Process next dispatch and headers */
if((PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_IPHC_MASK) == SICSLOWPAN_DISPATCH_IPHC) {
LOG_INFO("input: IPHC\n");
LOG_DBG("uncompression: IPHC dispatch\n");
uncompress_hdr_iphc(buffer, frag_size);
} else if(PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] == SICSLOWPAN_DISPATCH_IPV6) {
LOG_INFO("input: IPV6\n");
LOG_DBG("uncompression: IPV6 dispatch\n");
packetbuf_hdr_len += SICSLOWPAN_IPV6_HDR_LEN;
/* Put uncompressed IP header in sicslowpan_buf. */
@ -1871,8 +1906,8 @@ input(void)
packetbuf_hdr_len += UIP_IPH_LEN;
uncomp_hdr_len += UIP_IPH_LEN;
} else {
LOG_ERR("input: unknown dispatch: 0x%02x\n",
PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH]);
LOG_ERR("uncompression: unknown dispatch: 0x%02x\n",
PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_IPHC_MASK);
return;
}
@ -1887,18 +1922,25 @@ input(void)
* If this is a subsequent fragment, this is the contrary.
*/
if(packetbuf_datalen() < packetbuf_hdr_len) {
LOG_ERR("packet dropped due to header > total packet\n");
LOG_ERR("input: packet dropped due to header > total packet\n");
return;
}
packetbuf_payload_len = packetbuf_datalen() - packetbuf_hdr_len;
#if SICSLOWPAN_CONF_FRAG
if(is_fragment) {
LOG_INFO("input: fragment (tag %d, payload %d, offset %d) -- %u %u\n",
frag_tag, packetbuf_payload_len, frag_offset << 3, packetbuf_datalen(), packetbuf_hdr_len);
}
#endif /*SICSLOWPAN_CONF_FRAG*/
/* Sanity-check size of incoming packet to avoid buffer overflow */
{
int req_size = UIP_LLH_LEN + uncomp_hdr_len + (uint16_t)(frag_offset << 3)
+ packetbuf_payload_len;
if(req_size > sizeof(uip_buf)) {
LOG_ERR(
"packet dropped, minimum required IP_BUF size: %d+%d+%d+%d=%d (current size: %u)\n",
"input: packet dropped, minimum required IP_BUF size: %d+%d+%d+%d=%d (current size: %u)\n",
UIP_LLH_LEN, uncomp_hdr_len, (uint16_t)(frag_offset << 3),
packetbuf_payload_len, req_size, (unsigned)sizeof(uip_buf));
return;
@ -1943,12 +1985,12 @@ input(void)
#else
uip_len = packetbuf_payload_len + uncomp_hdr_len;
#endif /* SICSLOWPAN_CONF_FRAG */
LOG_INFO("input: IP packet ready (length %d)\n",
LOG_INFO("input: received IPv6 packet with len %d\n",
uip_len);
if(LOG_DBG_ENABLED) {
uint16_t ndx;
LOG_DBG("after decompression %u:", UIP_IP_BUF->len[1]);
LOG_DBG("uncompression: after (%u):", UIP_IP_BUF->len[1]);
for (ndx = 0; ndx < UIP_IP_BUF->len[1] + 40; ndx++) {
uint8_t data = ((uint8_t *) (UIP_IP_BUF))[ndx];
LOG_DBG_("%02x", data);

View File

@ -1089,7 +1089,7 @@ uip_process(uint8_t flag)
if((UIP_IP_BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */
UIP_STAT(++uip_stat.ip.drop);
UIP_STAT(++uip_stat.ip.vhlerr);
LOG_ERR("invalid version.");
LOG_ERR("invalid version\n");
goto drop;
}
/*

View File

@ -47,7 +47,7 @@
/*---------------------------------------------------------------------------*/
/* Log configuration */
#include "sys/log.h"
#define LOG_MODULE "BR"
#define LOG_MODULE "BR-MAC"
#define LOG_LEVEL LOG_LEVEL_NONE
#define MAX_CALLBACKS 16
@ -111,11 +111,12 @@ send_packet(mac_callback_t sent, void *ptr)
/* Will make it send only DATA packets... for now */
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
/* printf("Sending packet of type: %s \n", get_frame_type(packetbuf_attr(PACKETBUF_ATTR_FRAME_TYPE))); */
LOG_INFO("sending packet (%u bytes)\n", packetbuf_datalen());
if(NETSTACK_FRAMER.create() < 0) {
/* Failed to allocate space for headers */
LOG_WARN("br-rdc: send failed, too large header\n");
LOG_WARN("send failed, too large header\n");
mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1);
} else {
/* here we send the data over SLIP to the radio-chip */
@ -124,7 +125,7 @@ send_packet(mac_callback_t sent, void *ptr)
size = packetutils_serialize_atts(&buf[3], sizeof(buf) - 3);
#endif
if(size < 0 || size + packetbuf_totlen() + 3 > sizeof(buf)) {
LOG_WARN("br-rdc: send failed, too large header\n");
LOG_WARN("send failed, too large header\n");
mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1);
} else {
sid = setup_callback(sent, ptr);
@ -145,7 +146,7 @@ static void
packet_input(void)
{
if(NETSTACK_FRAMER.parse() < 0) {
LOG_DBG("br-rdc: failed to parse %u\n", packetbuf_datalen());
LOG_DBG("failed to parse %u\n", packetbuf_datalen());
} else {
NETSTACK_NETWORK.input();
}

View File

@ -0,0 +1,252 @@
<?xml version="1.0" encoding="UTF-8"?>
<simconf>
<project EXPORT="discard">[APPS_DIR]/mrm</project>
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
<project EXPORT="discard">[APPS_DIR]/avrora</project>
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
<simulation>
<title>My simulation</title>
<speedlimit>1.0</speedlimit>
<randomseed>123456</randomseed>
<motedelay_us>1000000</motedelay_us>
<radiomedium>
org.contikios.cooja.radiomediums.UDGM
<transmitting_range>50.0</transmitting_range>
<interference_range>100.0</interference_range>
<success_ratio_tx>1.0</success_ratio_tx>
<success_ratio_rx>1.0</success_ratio_rx>
</radiomedium>
<events>
<logoutput>40000</logoutput>
</events>
<motetype>
org.contikios.cooja.contikimote.ContikiMoteType
<identifier>mtype295</identifier>
<description>Cooja Mote Type #1</description>
<source>[CONTIKI_DIR]/examples/rpl-border-router/border-router.c</source>
<commands>make TARGET=cooja clean
make -j border-router.cooja TARGET=cooja</commands>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiEEPROM</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<motetype>
org.contikios.cooja.contikimote.ContikiMoteType
<identifier>mtype686</identifier>
<description>Cooja Mote Type #2</description>
<source>[CONTIKI_DIR]/examples/hello-world/hello-world.c</source>
<commands>make TARGET=cooja clean
make -j hello-world.cooja TARGET=cooja</commands>
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiEEPROM</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
<symbols>false</symbols>
</motetype>
<mote>
<interface_config>
org.contikios.cooja.interfaces.Position
<x>54.36775767371176</x>
<y>24.409055040864118</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
<id>1</id>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
</interface_config>
<motetype_identifier>mtype295</motetype_identifier>
</mote>
<mote>
<interface_config>
org.contikios.cooja.interfaces.Position
<x>83.54989222799365</x>
<y>52.63050856506214</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
<id>2</id>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
</interface_config>
<motetype_identifier>mtype686</motetype_identifier>
</mote>
<mote>
<interface_config>
org.contikios.cooja.interfaces.Position
<x>108.91767775240822</x>
<y>78.59778809170032</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
<id>3</id>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
</interface_config>
<motetype_identifier>mtype686</motetype_identifier>
</mote>
<mote>
<interface_config>
org.contikios.cooja.interfaces.Position
<x>139.91021061864723</x>
<y>98.34190023350419</y>
<z>0.0</z>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
<id>4</id>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiRadio
<bitrate>250.0</bitrate>
</interface_config>
<interface_config>
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
</interface_config>
<motetype_identifier>mtype686</motetype_identifier>
</mote>
</simulation>
<plugin>
org.contikios.cooja.plugins.SimControl
<width>280</width>
<z>1</z>
<height>160</height>
<location_x>400</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.Visualizer
<plugin_config>
<moterelations>true</moterelations>
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
<viewport>1.9798610460263038 0.0 0.0 1.9798610460263038 -61.112037797038525 -1.2848438586294648</viewport>
</plugin_config>
<width>400</width>
<z>4</z>
<height>400</height>
<location_x>1</location_x>
<location_y>1</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.LogListener
<plugin_config>
<filter>ID:4</filter>
<formatted_time />
<coloring />
</plugin_config>
<width>1404</width>
<z>2</z>
<height>240</height>
<location_x>400</location_x>
<location_y>160</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.TimeLine
<plugin_config>
<mote>0</mote>
<mote>1</mote>
<mote>2</mote>
<mote>3</mote>
<showRadioRXTX />
<showRadioHW />
<showLEDs />
<zoomfactor>500.0</zoomfactor>
</plugin_config>
<width>1804</width>
<z>6</z>
<height>166</height>
<location_x>0</location_x>
<location_y>753</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.Notes
<plugin_config>
<notes>Enter notes here</notes>
<decorations>true</decorations>
</plugin_config>
<width>1124</width>
<z>5</z>
<height>160</height>
<location_x>680</location_x>
<location_y>0</location_y>
</plugin>
<plugin>
org.contikios.cooja.serialsocket.SerialSocketServer
<mote_arg>0</mote_arg>
<plugin_config>
<port>60001</port>
<bound>true</bound>
</plugin_config>
<width>362</width>
<z>3</z>
<height>116</height>
<location_x>13</location_x>
<location_y>414</location_y>
</plugin>
<plugin>
org.contikios.cooja.plugins.ScriptRunner
<plugin_config>
<script>TIMEOUT(10000000000); /* milliseconds. no action at timeout */
/* Set simulaion speed to real time */
sim.setSpeedLimit(1.0);</script>
<active>true</active>
</plugin_config>
<width>600</width>
<z>0</z>
<height>700</height>
<location_x>1037</location_x>
<location_y>40</location_y>
</plugin>
</simconf>

View File

@ -0,0 +1,9 @@
#!/bin/bash
# Contiki directory
CONTIKI=$1
# Simulation file
BASENAME=01-border-router-cooja
bash test-border-router.sh $CONTIKI $BASENAME fd00::204:4:4:4 60 600 2

View File

@ -12,6 +12,12 @@ IPADDR=$3
# Time allocated for convergence
WAIT_TIME=$4
# Payload len. Default is ping6's default, 56.
PING_SIZE=${5:-56}
# Inter-ping delay. Default is ping6's default, 1s.
PING_DELAY=${6:-1}
# ICMP request-reply count
COUNT=5
@ -31,7 +37,7 @@ sleep $WAIT_TIME
# Do ping
echo "Pinging"
ping6 $IPADDR -c $COUNT | tee $BASENAME.scriptlog
ping6 $IPADDR -c $COUNT -s $PING_SIZE -i $PING_DELAY | tee $BASENAME.scriptlog
# Fetch ping6 status code (not $? because this is piped)
STATUS=${PIPESTATUS[0]}
REPLIES=`grep -c 'icmp_seq=' $BASENAME.scriptlog`