Merge pull request #1739 from simonduq/pr/tsch-seqno

Improved TSCH sequence number handling
This commit is contained in:
Nicolas Tsiftes 2016-08-16 14:49:21 +02:00 committed by GitHub
commit 4c7d8d0214
4 changed files with 24 additions and 57 deletions

View file

@ -86,14 +86,16 @@ create_frame(int type, int do_create)
params.fcf.frame_pending = packetbuf_attr(PACKETBUF_ATTR_PENDING);
if(packetbuf_holds_broadcast()) {
params.fcf.ack_required = 0;
/* Suppress seqno on broadcast if supported (frame v2 or more) */
params.fcf.sequence_number_suppression = FRAME802154_VERSION >= FRAME802154_IEEE802154E_2012;
} else {
params.fcf.ack_required = packetbuf_attr(PACKETBUF_ATTR_MAC_ACK);
params.fcf.sequence_number_suppression = FRAME802154_SUPPR_SEQNO;
}
/* We do not compress PAN ID in outgoing frames, i.e. include one PAN ID (dest by default)
* There is one exception, seemingly a typo in Table 2a: rows 2 and 3: when there is no
* source nor destination address, we have dest PAN ID iff compression is *set*. */
params.fcf.panid_compression = 0;
params.fcf.sequence_number_suppression = FRAME802154_SUPPR_SEQNO;
/* Insert IEEE 802.15.4 version bits. */
params.fcf.frame_version = FRAME802154_VERSION;

View file

@ -189,7 +189,7 @@ tsch_packet_parse_eack(const uint8_t *buf, int buf_size,
/*---------------------------------------------------------------------------*/
/* Create an EB packet */
int
tsch_packet_create_eb(uint8_t *buf, int buf_size, uint8_t seqno,
tsch_packet_create_eb(uint8_t *buf, int buf_size,
uint8_t *hdr_len, uint8_t *tsch_sync_ie_offset)
{
int ret = 0;
@ -210,8 +210,7 @@ tsch_packet_create_eb(uint8_t *buf, int buf_size, uint8_t seqno,
p.fcf.frame_version = FRAME802154_IEEE802154E_2012;
p.fcf.src_addr_mode = LINKADDR_SIZE > 2 ? FRAME802154_LONGADDRMODE : FRAME802154_SHORTADDRMODE;
p.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
p.seq = seqno;
p.fcf.sequence_number_suppression = FRAME802154_SUPPR_SEQNO;
p.fcf.sequence_number_suppression = 1;
/* It is important not to compress PAN ID, as this would result in not including either
* source nor destination PAN ID, leaving potential joining devices unaware of the PAN ID. */
p.fcf.panid_compression = 0;

View file

@ -94,7 +94,7 @@ int tsch_packet_parse_eack(const uint8_t *buf, int buf_size,
uint8_t seqno, frame802154_t *frame, struct ieee802154_ies *ies, uint8_t *hdr_len);
/* Create an EB packet */
int tsch_packet_create_eb(uint8_t *buf, int buf_size,
uint8_t seqno, uint8_t *hdr_len, uint8_t *tsch_sync_ie_ptr);
uint8_t *hdr_len, uint8_t *tsch_sync_ie_ptr);
/* Update ASN in EB packet */
int tsch_packet_update_eb(uint8_t *buf, int buf_size, uint8_t tsch_sync_ie_offset);
/* Parse EB and extract ASN and join priority */

View file

@ -54,6 +54,7 @@
#include "net/mac/tsch/tsch-log.h"
#include "net/mac/tsch/tsch-packet.h"
#include "net/mac/tsch/tsch-security.h"
#include "net/mac/mac-sequence.h"
#include "lib/random.h"
#if FRAME802154_VERSION < FRAME802154_IEEE802154E_2012
@ -76,22 +77,6 @@ void uip_ds6_link_neighbor_callback(int status, int numtx);
#endif /* NETSTACK_CONF_WITH_IPV6 */
#endif /* TSCH_LINK_NEIGHBOR_CALLBACK */
/* 802.15.4 duplicate frame detection */
struct seqno {
linkaddr_t sender;
uint8_t seqno;
};
/* Size of the sequence number history */
#ifdef NETSTACK_CONF_MAC_SEQNO_HISTORY
#define MAX_SEQNOS NETSTACK_CONF_MAC_SEQNO_HISTORY
#else /* NETSTACK_CONF_MAC_SEQNO_HISTORY */
#define MAX_SEQNOS 8
#endif /* NETSTACK_CONF_MAC_SEQNO_HISTORY */
/* Seqno history */
static struct seqno received_seqnos[MAX_SEQNOS];
/* Let TSCH select a time source with no help of an upper layer.
* We do so using statistics from incoming EBs */
#if TSCH_AUTOSELECT_TIME_SOURCE
@ -150,7 +135,7 @@ struct asn_t current_asn;
/* Device rank or join priority:
* For PAN coordinator: 0 -- lower is better */
uint8_t tsch_join_priority;
/* The current TSCH sequence number, used for both data and EBs */
/* The current TSCH sequence number, used for unicast data frames only */
static uint8_t tsch_packet_seqno = 0;
/* Current period for EB output */
static clock_time_t tsch_current_eb_period;
@ -744,12 +729,7 @@ PROCESS_THREAD(tsch_send_eb_process, ev, data)
uint8_t tsch_sync_ie_offset;
/* Prepare the EB packet and schedule it to be sent */
packetbuf_clear();
/* We don't use seqno 0 */
if(++tsch_packet_seqno == 0) {
tsch_packet_seqno++;
}
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_BEACONFRAME);
packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, tsch_packet_seqno);
#if LLSEC802154_ENABLED
if(tsch_is_pan_secured) {
/* Set security level, key id and index */
@ -759,7 +739,7 @@ PROCESS_THREAD(tsch_send_eb_process, ev, data)
}
#endif /* LLSEC802154_ENABLED */
eb_len = tsch_packet_create_eb(packetbuf_dataptr(), PACKETBUF_SIZE,
tsch_packet_seqno, &hdr_len, &tsch_sync_ie_offset);
&hdr_len, &tsch_sync_ie_offset);
if(eb_len != 0) {
struct tsch_packet *p;
packetbuf_set_datalen(eb_len);
@ -892,14 +872,14 @@ send_packet(mac_callback_t sent, void *ptr)
return;
}
/* PACKETBUF_ATTR_MAC_SEQNO cannot be zero, due to a pecuilarity
in framer-802154.c. */
if(++tsch_packet_seqno == 0) {
tsch_packet_seqno++;
}
/* Ask for ACK if we are sending anything other than broadcast */
if(!linkaddr_cmp(addr, &linkaddr_null)) {
/* PACKETBUF_ATTR_MAC_SEQNO cannot be zero, due to a pecuilarity
in framer-802154.c. */
if(++tsch_packet_seqno == 0) {
tsch_packet_seqno++;
}
packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, tsch_packet_seqno);
packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
} else {
/* Broadcast packets shall be added to broadcast queue
@ -909,7 +889,6 @@ send_packet(mac_callback_t sent, void *ptr)
}
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, tsch_packet_seqno);
#if LLSEC802154_ENABLED
if(tsch_is_pan_secured) {
@ -962,28 +941,15 @@ packet_input(void)
/* Seqno of 0xffff means no seqno */
if(packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO) != 0xffff) {
/* Check for duplicate packet by comparing the sequence number
of the incoming packet with the last few ones we saw. */
int i;
for(i = 0; i < MAX_SEQNOS; ++i) {
if(packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO) == received_seqnos[i].seqno &&
linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER),
&received_seqnos[i].sender)) {
/* Drop the packet. */
PRINTF("TSCH:! drop dup ll from %u seqno %u\n",
TSCH_LOG_ID_FROM_LINKADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)),
packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO));
duplicate = 1;
}
}
if(!duplicate) {
for(i = MAX_SEQNOS - 1; i > 0; --i) {
memcpy(&received_seqnos[i], &received_seqnos[i - 1],
sizeof(struct seqno));
}
received_seqnos[0].seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO);
linkaddr_copy(&received_seqnos[0].sender,
packetbuf_addr(PACKETBUF_ADDR_SENDER));
/* Check for duplicates */
duplicate = mac_sequence_is_duplicate();
if(duplicate) {
/* Drop the packet. */
PRINTF("TSCH:! drop dup ll from %u seqno %u\n",
TSCH_LOG_ID_FROM_LINKADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)),
packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO));
} else {
mac_sequence_register_seqno();
}
}