From a5a2a0510181de24f269e25bffe7f2c376f6b2fd Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 26 Mar 2018 11:15:17 -0700 Subject: [PATCH 01/10] TSCH: implement burst mode --- os/net/mac/tsch/tsch-const.h | 1 + os/net/mac/tsch/tsch-packet.c | 14 ++++++++ os/net/mac/tsch/tsch-packet.h | 4 +++ os/net/mac/tsch/tsch-slot-operation.c | 49 ++++++++++++++++++++++++--- os/net/mac/tsch/tsch-slot-operation.h | 2 ++ 5 files changed, 65 insertions(+), 5 deletions(-) diff --git a/os/net/mac/tsch/tsch-const.h b/os/net/mac/tsch/tsch-const.h index 81ca7ffa8..51e7d0625 100644 --- a/os/net/mac/tsch/tsch-const.h +++ b/os/net/mac/tsch/tsch-const.h @@ -53,6 +53,7 @@ #define LINK_OPTION_RX 2 #define LINK_OPTION_SHARED 4 #define LINK_OPTION_TIME_KEEPING 8 +#define LINK_OPTION_BURST 16 /* Default IEEE 802.15.4e hopping sequences, obtained from https://gist.github.com/twatteyne/2e22ee3c1a802b685695 */ /* 16 channels, sequence length 16 */ diff --git a/os/net/mac/tsch/tsch-packet.c b/os/net/mac/tsch/tsch-packet.c index 64f03b588..5f6cb6b54 100644 --- a/os/net/mac/tsch/tsch-packet.c +++ b/os/net/mac/tsch/tsch-packet.c @@ -459,4 +459,18 @@ tsch_packet_parse_eb(const uint8_t *buf, int buf_size, return curr_len; } /*---------------------------------------------------------------------------*/ +/* Set frame pending bit in a packet (whose header was already build) */ +void +tsch_packet_set_frame_pending(uint8_t *buf, int buf_size) +{ + buf[0] |= (1 << 4); +} +/*---------------------------------------------------------------------------*/ +/* Get frame pending bit from a packet */ +int +tsch_packet_get_frame_pending(uint8_t *buf, int buf_size) +{ + return (buf[0] >> 4) & 1; +} +/*---------------------------------------------------------------------------*/ /** @} */ diff --git a/os/net/mac/tsch/tsch-packet.h b/os/net/mac/tsch/tsch-packet.h index 6b05d6653..a7426ebac 100644 --- a/os/net/mac/tsch/tsch-packet.h +++ b/os/net/mac/tsch/tsch-packet.h @@ -101,6 +101,10 @@ int tsch_packet_update_eb(uint8_t *buf, int buf_size, uint8_t tsch_sync_ie_offse int tsch_packet_parse_eb(const uint8_t *buf, int buf_size, frame802154_t *frame, struct ieee802154_ies *ies, uint8_t *hdrlen, int frame_without_mic); +/* Set frame pending bit in a packet (whose header was already build) */ +void tsch_packet_set_frame_pending(uint8_t *buf, int buf_size); +/* Get frame pending bit from a packet */ +int tsch_packet_get_frame_pending(uint8_t *buf, int buf_size); #endif /* __TSCH_PACKET_H__ */ /** @} */ diff --git a/os/net/mac/tsch/tsch-slot-operation.c b/os/net/mac/tsch/tsch-slot-operation.c index c4bb25e88..6b47b4ebf 100644 --- a/os/net/mac/tsch/tsch-slot-operation.c +++ b/os/net/mac/tsch/tsch-slot-operation.c @@ -167,6 +167,11 @@ static struct tsch_link *backup_link = NULL; static struct tsch_packet *current_packet = NULL; static struct tsch_neighbor *current_neighbor = NULL; +/* Indicates whether an extra link is needed to handle the current burst */ +static int burst_link_scheduled = 0; +/* Counts the length of the current burst */ +int tsch_current_burst_count = 0; + /* Protothread for association */ PT_THREAD(tsch_scan(struct pt *pt)); /* Protothread for slot operation, called from rtimer interrupt @@ -456,6 +461,8 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) /* is this a broadcast packet? (wait for ack?) */ static uint8_t is_broadcast; static rtimer_clock_t tx_start_time; + /* Did we set the frame pending bit to request an extra burst link? */ + static int burst_link_requested; #if CCA_ENABLED static uint8_t cca_status; @@ -466,6 +473,13 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) packet_len = queuebuf_datalen(current_packet->qb); /* is this a broadcast packet? (wait for ack?) */ is_broadcast = current_neighbor->is_broadcast; + /* Unicast. More packets in queue for the neighbor? */ + burst_link_requested = 0; + if(!is_broadcast && (current_link->link_options & LINK_OPTION_BURST) + && tsch_queue_packet_count(¤t_neighbor->addr) > 1) { + burst_link_requested = 1; + tsch_packet_set_frame_pending(packet, packet_len); + } /* read seqno from payload */ seqno = ((uint8_t *)(packet))[2]; /* if this is an EB, then update its Sync-IE */ @@ -618,6 +632,12 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) tsch_schedule_keepalive(); } mac_tx_status = MAC_TX_OK; + + /* We requested an extra slot and got an ack. This means + the extra slot will be scheduled at the received */ + if(burst_link_requested) { + burst_link_scheduled = 1; + } } else { mac_tx_status = MAC_TX_NOACK; } @@ -844,6 +864,9 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)) TSCH_DEBUG_RX_EVENT(); NETSTACK_RADIO.transmit(ack_len); tsch_radio_off(TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT); + + /* Schedule a burst link iff the frame pending bit was set */ + burst_link_scheduled = tsch_packet_get_frame_pending(current_input->payload, current_input->len); } } @@ -930,6 +953,8 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr)) /* Reset drift correction */ drift_correction = 0; is_drift_correction_used = 0; + /* For the packet burst mechanism */ + burst_link_scheduled = 0; /* Get a packet ready to be sent */ current_packet = get_packet_and_neighbor_for_link(current_link, ¤t_neighbor); /* There is no packet to send, and this link does not have Rx flag. Instead of doing @@ -993,13 +1018,27 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr)) tsch_queue_update_all_backoff_windows(¤t_link->addr); } - /* Get next active link */ - current_link = tsch_schedule_get_next_active_link(&tsch_current_asn, ×lot_diff, &backup_link); - if(current_link == NULL) { - /* There is no next link. Fall back to default - * behavior: wake up at the next slot. */ + /* A burst link was scheduled. Replay the current link at the + next time offset */ + if(burst_link_scheduled) { timeslot_diff = 1; + backup_link = NULL; + /* Keep track of the number of repetitions */ + tsch_current_burst_count++; + } else { + /* Get next active link */ + current_link = tsch_schedule_get_next_active_link(&tsch_current_asn, ×lot_diff, &backup_link); + if(current_link == NULL) { + /* There is no next link. Fall back to default + * behavior: wake up at the next slot. */ + timeslot_diff = 1; + } else { + /* Reset burst index now that the link was scheduled from + normal schedule (as opposed to from ongoing burst) */ + tsch_current_burst_count = 0; + } } + /* Update ASN */ TSCH_ASN_INC(tsch_current_asn, timeslot_diff); /* Time to next wake up */ diff --git a/os/net/mac/tsch/tsch-slot-operation.h b/os/net/mac/tsch/tsch-slot-operation.h index 1c71c5587..b1c05697b 100644 --- a/os/net/mac/tsch/tsch-slot-operation.h +++ b/os/net/mac/tsch/tsch-slot-operation.h @@ -57,6 +57,8 @@ extern struct ringbufindex input_ringbuf; extern struct input_packet input_array[TSCH_MAX_INCOMING_PACKETS]; /* Last clock_time_t where synchronization happened */ extern clock_time_t last_sync_time; +/* Counts the length of the current burst */ +extern int tsch_current_burst_count; /********** Functions *********/ From c41057fc1be9720087ce0a10fb1f9af74c8aa622 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 26 Mar 2018 11:15:45 -0700 Subject: [PATCH 02/10] TSCH: cleaner logging of burst mode --- os/net/mac/tsch/tsch-log.c | 6 ++++-- os/net/mac/tsch/tsch-log.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/os/net/mac/tsch/tsch-log.c b/os/net/mac/tsch/tsch-log.c index d27dac064..5aa6f1e69 100644 --- a/os/net/mac/tsch/tsch-log.c +++ b/os/net/mac/tsch/tsch-log.c @@ -82,9 +82,10 @@ tsch_log_process_pending(void) printf("[INFO: TSCH-LOG ] {asn %02x.%08lx link-NULL} ", log->asn.ms1b, log->asn.ls4b); } else { struct tsch_slotframe *sf = tsch_schedule_get_slotframe_by_handle(log->link->slotframe_handle); - printf("[INFO: TSCH-LOG ] {asn %02x.%08lx link %2u %3u %3u %2u ch %2u} ", + printf("[INFO: TSCH-LOG ] {asn %02x.%08lx link %2u %3u %3u %2u %2u ch %2u} ", log->asn.ms1b, log->asn.ls4b, - log->link->slotframe_handle, sf ? sf->size.val : 0, log->link->timeslot, log->link->channel_offset, + log->link->slotframe_handle, sf ? sf->size.val : 0, + log->burst_count, log->link->timeslot + log->burst_count, log->link->channel_offset, tsch_calculate_channel(&log->asn, log->link->channel_offset)); } switch(log->type) { @@ -135,6 +136,7 @@ tsch_log_prepare_add(void) struct tsch_log_t *log = &log_array[log_index]; log->asn = tsch_current_asn; log->link = current_link; + log->burst_count = tsch_current_burst_count; return log; } else { log_dropped++; diff --git a/os/net/mac/tsch/tsch-log.h b/os/net/mac/tsch/tsch-log.h index 468eff869..8064922fd 100644 --- a/os/net/mac/tsch/tsch-log.h +++ b/os/net/mac/tsch/tsch-log.h @@ -80,6 +80,7 @@ struct tsch_log_t { } type; struct tsch_asn_t asn; struct tsch_link *link; + uint8_t burst_count; union { char message[48]; struct { From d3b8b80b2808c29dcb37532cc7f675453ad42e27 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 26 Mar 2018 11:22:31 -0700 Subject: [PATCH 03/10] TSCH: add option to run 6TiSCH minimal with burst mode enabled --- os/net/mac/tsch/tsch-conf.h | 7 +++++++ os/net/mac/tsch/tsch-schedule.c | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/os/net/mac/tsch/tsch-conf.h b/os/net/mac/tsch/tsch-conf.h index 3ee47b9cb..934e0884f 100644 --- a/os/net/mac/tsch/tsch-conf.h +++ b/os/net/mac/tsch/tsch-conf.h @@ -317,6 +317,13 @@ #define TSCH_SCHEDULE_WITH_6TISCH_MINIMAL (!(BUILD_WITH_ORCHESTRA)) #endif +/* Add burst mode to 6TiSCH minimal schedule */ +#ifdef TSCH_SCHEDULE_CONF_WITH_6TISCH_MINIMAL_WITH_BURST +#define TSCH_SCHEDULE_WITH_6TISCH_MINIMAL_WITH_BURST TSCH_SCHEDULE_CONF_WITH_6TISCH_MINIMAL_WITH_BURST +#else +#define TSCH_SCHEDULE_WITH_6TISCH_MINIMAL_WITH_BURST 0 +#endif + /* 6TiSCH Minimal schedule slotframe length */ #ifdef TSCH_SCHEDULE_CONF_DEFAULT_LENGTH #define TSCH_SCHEDULE_DEFAULT_LENGTH TSCH_SCHEDULE_CONF_DEFAULT_LENGTH diff --git a/os/net/mac/tsch/tsch-schedule.c b/os/net/mac/tsch/tsch-schedule.c index 70a6b92ae..d5bf49653 100644 --- a/os/net/mac/tsch/tsch-schedule.c +++ b/os/net/mac/tsch/tsch-schedule.c @@ -423,7 +423,8 @@ tsch_schedule_create_minimal(void) * but is required according to 802.15.4e if also used for EB transmission. * Timeslot: 0, channel offset: 0. */ tsch_schedule_add_link(sf_min, - LINK_OPTION_RX | LINK_OPTION_TX | LINK_OPTION_SHARED | LINK_OPTION_TIME_KEEPING, + LINK_OPTION_RX | LINK_OPTION_TX | LINK_OPTION_SHARED | LINK_OPTION_TIME_KEEPING + | (TSCH_SCHEDULE_WITH_6TISCH_MINIMAL_WITH_BURST ? LINK_OPTION_BURST : 0), LINK_TYPE_ADVERTISING, &tsch_broadcast_address, 0, 0); } From 3fe846dbada52ef4b1a738340ff073514bb65a2e Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Mon, 26 Mar 2018 11:35:35 -0700 Subject: [PATCH 04/10] TSCH burst mode: bounded burst lengths --- os/net/mac/tsch/tsch-conf.h | 13 ++++++++++--- os/net/mac/tsch/tsch-schedule.c | 2 +- os/net/mac/tsch/tsch-slot-operation.c | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/os/net/mac/tsch/tsch-conf.h b/os/net/mac/tsch/tsch-conf.h index 934e0884f..afd90aaef 100644 --- a/os/net/mac/tsch/tsch-conf.h +++ b/os/net/mac/tsch/tsch-conf.h @@ -318,10 +318,17 @@ #endif /* Add burst mode to 6TiSCH minimal schedule */ -#ifdef TSCH_SCHEDULE_CONF_WITH_6TISCH_MINIMAL_WITH_BURST -#define TSCH_SCHEDULE_WITH_6TISCH_MINIMAL_WITH_BURST TSCH_SCHEDULE_CONF_WITH_6TISCH_MINIMAL_WITH_BURST +#ifdef TSCH_CONF_WITH_6TISCH_MINIMAL_WITH_BURST +#define TSCH_WITH_6TISCH_MINIMAL_WITH_BURST TSCH_CONF_WITH_6TISCH_MINIMAL_WITH_BURST #else -#define TSCH_SCHEDULE_WITH_6TISCH_MINIMAL_WITH_BURST 0 +#define TSCH_WITH_6TISCH_MINIMAL_WITH_BURST 0 +#endif + +/* Set an upper bound on burst length */ +#ifdef TSCH_CONF_BURST_MAX_LEN +#define TSCH_BURST_MAX_LEN TSCH_CONF_BURST_MAX_LEN +#else +#define TSCH_BURST_MAX_LEN 32 #endif /* 6TiSCH Minimal schedule slotframe length */ diff --git a/os/net/mac/tsch/tsch-schedule.c b/os/net/mac/tsch/tsch-schedule.c index d5bf49653..a03363eb9 100644 --- a/os/net/mac/tsch/tsch-schedule.c +++ b/os/net/mac/tsch/tsch-schedule.c @@ -424,7 +424,7 @@ tsch_schedule_create_minimal(void) * Timeslot: 0, channel offset: 0. */ tsch_schedule_add_link(sf_min, LINK_OPTION_RX | LINK_OPTION_TX | LINK_OPTION_SHARED | LINK_OPTION_TIME_KEEPING - | (TSCH_SCHEDULE_WITH_6TISCH_MINIMAL_WITH_BURST ? LINK_OPTION_BURST : 0), + | (TSCH_WITH_6TISCH_MINIMAL_WITH_BURST ? LINK_OPTION_BURST : 0), LINK_TYPE_ADVERTISING, &tsch_broadcast_address, 0, 0); } diff --git a/os/net/mac/tsch/tsch-slot-operation.c b/os/net/mac/tsch/tsch-slot-operation.c index 6b47b4ebf..a2e9982fe 100644 --- a/os/net/mac/tsch/tsch-slot-operation.c +++ b/os/net/mac/tsch/tsch-slot-operation.c @@ -476,6 +476,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) /* Unicast. More packets in queue for the neighbor? */ burst_link_requested = 0; if(!is_broadcast && (current_link->link_options & LINK_OPTION_BURST) + && tsch_current_burst_count + 1 < TSCH_BURST_MAX_LEN && tsch_queue_packet_count(¤t_neighbor->addr) > 1) { burst_link_requested = 1; tsch_packet_set_frame_pending(packet, packet_len); From 5607308eed2540cc3fe10edf7c5902b6152ef64e Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sun, 15 Apr 2018 04:18:33 -0700 Subject: [PATCH 05/10] Added doxygen for TSCH frame pending bit functions --- os/net/mac/tsch/tsch-packet.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/os/net/mac/tsch/tsch-packet.h b/os/net/mac/tsch/tsch-packet.h index a7426ebac..cdf7c7bed 100644 --- a/os/net/mac/tsch/tsch-packet.h +++ b/os/net/mac/tsch/tsch-packet.h @@ -101,9 +101,18 @@ int tsch_packet_update_eb(uint8_t *buf, int buf_size, uint8_t tsch_sync_ie_offse int tsch_packet_parse_eb(const uint8_t *buf, int buf_size, frame802154_t *frame, struct ieee802154_ies *ies, uint8_t *hdrlen, int frame_without_mic); -/* Set frame pending bit in a packet (whose header was already build) */ +/** + * \brief Set frame pending bit in a packet (whose header was already build) + * \param buf The buffer where the packet resides + * \param buf_size The buffer size + */ void tsch_packet_set_frame_pending(uint8_t *buf, int buf_size); -/* Get frame pending bit from a packet */ +/** + * \brief Get frame pending bit from a packet + * \param buf The buffer where the packet resides + * \param buf_size The buffer size + * \return The value of the frame pending bit, 1 or 0 + */ int tsch_packet_get_frame_pending(uint8_t *buf, int buf_size); #endif /* __TSCH_PACKET_H__ */ From 243386044158d4b792976d8dce48526b13846ede Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sat, 12 May 2018 10:49:44 -0700 Subject: [PATCH 06/10] TSCH burst mode: do not channel hop within burst --- os/net/mac/tsch/tsch-slot-operation.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/os/net/mac/tsch/tsch-slot-operation.c b/os/net/mac/tsch/tsch-slot-operation.c index a2e9982fe..7a26e4d81 100644 --- a/os/net/mac/tsch/tsch-slot-operation.c +++ b/os/net/mac/tsch/tsch-slot-operation.c @@ -171,6 +171,8 @@ static struct tsch_neighbor *current_neighbor = NULL; static int burst_link_scheduled = 0; /* Counts the length of the current burst */ int tsch_current_burst_count = 0; +/* The physical channel of the current burst */ +static uint16_t burst_current_channel = 0; /* Protothread for association */ PT_THREAD(tsch_scan(struct pt *pt)); @@ -954,8 +956,6 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr)) /* Reset drift correction */ drift_correction = 0; is_drift_correction_used = 0; - /* For the packet burst mechanism */ - burst_link_scheduled = 0; /* Get a packet ready to be sent */ current_packet = get_packet_and_neighbor_for_link(current_link, ¤t_neighbor); /* There is no packet to send, and this link does not have Rx flag. Instead of doing @@ -966,8 +966,15 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr)) } is_active_slot = current_packet != NULL || (current_link->link_options & LINK_OPTION_RX); if(is_active_slot) { - /* Hop channel */ - current_channel = tsch_calculate_channel(&tsch_current_asn, current_link->channel_offset); + /* If we are in a burst, we stick to current channel instead of + * doing channel hopping, as per IEEE 802.15.4-2015 */ + if(burst_link_scheduled) { + current_channel = burst_current_channel; + burst_link_scheduled = 0; + } else { + /* Hop channel */ + current_channel = tsch_calculate_channel(&tsch_current_asn, current_link->channel_offset); + } NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, current_channel); /* Turn the radio on already here if configured so; necessary for radios with slow startup */ tsch_radio_on(TSCH_RADIO_CMD_ON_START_OF_TIMESLOT); @@ -986,6 +993,10 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr)) static struct pt slot_rx_pt; PT_SPAWN(&slot_operation_pt, &slot_rx_pt, tsch_rx_slot(&slot_rx_pt, t)); } + } else { + /* Make sure to end the burst in cast, for some reason, we were + * in a burst but now without any more packet to send. */ + burst_link_scheduled = 0; } TSCH_DEBUG_SLOT_END(); } @@ -1023,6 +1034,7 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr)) next time offset */ if(burst_link_scheduled) { timeslot_diff = 1; + burst_current_channel = current_channel; backup_link = NULL; /* Keep track of the number of repetitions */ tsch_current_burst_count++; From 0153566b928cb59ff02004dfb37033a560e5716f Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sat, 12 May 2018 10:53:24 -0700 Subject: [PATCH 07/10] TSCH burst mode: fix logging --- os/net/mac/tsch/tsch-log.c | 3 ++- os/net/mac/tsch/tsch-log.h | 1 + os/net/mac/tsch/tsch-slot-operation.c | 14 +++++++------- os/net/mac/tsch/tsch.h | 2 ++ 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/os/net/mac/tsch/tsch-log.c b/os/net/mac/tsch/tsch-log.c index 5aa6f1e69..e705f50ab 100644 --- a/os/net/mac/tsch/tsch-log.c +++ b/os/net/mac/tsch/tsch-log.c @@ -86,7 +86,7 @@ tsch_log_process_pending(void) log->asn.ms1b, log->asn.ls4b, log->link->slotframe_handle, sf ? sf->size.val : 0, log->burst_count, log->link->timeslot + log->burst_count, log->link->channel_offset, - tsch_calculate_channel(&log->asn, log->link->channel_offset)); + log->channel); } switch(log->type) { case tsch_log_tx: @@ -137,6 +137,7 @@ tsch_log_prepare_add(void) log->asn = tsch_current_asn; log->link = current_link; log->burst_count = tsch_current_burst_count; + log->channel = tsch_current_channel; return log; } else { log_dropped++; diff --git a/os/net/mac/tsch/tsch-log.h b/os/net/mac/tsch/tsch-log.h index 8064922fd..186cda120 100644 --- a/os/net/mac/tsch/tsch-log.h +++ b/os/net/mac/tsch/tsch-log.h @@ -81,6 +81,7 @@ struct tsch_log_t { struct tsch_asn_t asn; struct tsch_link *link; uint8_t burst_count; + uint8_t channel; union { char message[48]; struct { diff --git a/os/net/mac/tsch/tsch-slot-operation.c b/os/net/mac/tsch/tsch-slot-operation.c index 7a26e4d81..bc76b526e 100644 --- a/os/net/mac/tsch/tsch-slot-operation.c +++ b/os/net/mac/tsch/tsch-slot-operation.c @@ -155,7 +155,7 @@ static rtimer_clock_t volatile current_slot_start; static volatile int tsch_in_slot_operation = 0; /* If we are inside a slot, this tells the current channel */ -static uint8_t current_channel; +uint8_t tsch_current_channel; /* Info about the link, packet and neighbor of * the current (or next) slot */ @@ -172,7 +172,7 @@ static int burst_link_scheduled = 0; /* Counts the length of the current burst */ int tsch_current_burst_count = 0; /* The physical channel of the current burst */ -static uint16_t burst_current_channel = 0; +static uint16_t burst_tsch_current_channel = 0; /* Protothread for association */ PT_THREAD(tsch_scan(struct pt *pt)); @@ -772,7 +772,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)) NETSTACK_RADIO.get_value(RADIO_PARAM_LAST_RSSI, &radio_last_rssi); current_input->rx_asn = tsch_current_asn; current_input->rssi = (signed)radio_last_rssi; - current_input->channel = current_channel; + current_input->channel = tsch_current_channel; header_len = frame802154_parse((uint8_t *)current_input->payload, current_input->len, &frame); frame_valid = header_len > 0 && frame802154_check_dest_panid(&frame) && @@ -969,13 +969,13 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr)) /* If we are in a burst, we stick to current channel instead of * doing channel hopping, as per IEEE 802.15.4-2015 */ if(burst_link_scheduled) { - current_channel = burst_current_channel; + tsch_current_channel = burst_tsch_current_channel; burst_link_scheduled = 0; } else { /* Hop channel */ - current_channel = tsch_calculate_channel(&tsch_current_asn, current_link->channel_offset); + tsch_current_channel = tsch_calculate_channel(&tsch_current_asn, current_link->channel_offset); } - NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, current_channel); + NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, tsch_current_channel); /* Turn the radio on already here if configured so; necessary for radios with slow startup */ tsch_radio_on(TSCH_RADIO_CMD_ON_START_OF_TIMESLOT); /* Decide whether it is a TX/RX/IDLE or OFF slot */ @@ -1034,7 +1034,7 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr)) next time offset */ if(burst_link_scheduled) { timeslot_diff = 1; - burst_current_channel = current_channel; + burst_tsch_current_channel = tsch_current_channel; backup_link = NULL; /* Keep track of the number of repetitions */ tsch_current_burst_count++; diff --git a/os/net/mac/tsch/tsch.h b/os/net/mac/tsch/tsch.h index 0f108bd93..93b6e0d88 100644 --- a/os/net/mac/tsch/tsch.h +++ b/os/net/mac/tsch/tsch.h @@ -164,6 +164,8 @@ extern const linkaddr_t tsch_eb_address; extern struct tsch_asn_t tsch_current_asn; extern uint8_t tsch_join_priority; extern struct tsch_link *current_link; +/* If we are inside a slot, this tells the current channel */ +extern uint8_t tsch_current_channel; /* TSCH channel hopping sequence */ extern uint8_t tsch_hopping_sequence[TSCH_HOPPING_SEQUENCE_MAX_LEN]; extern struct tsch_asn_divisor_t tsch_hopping_sequence_length; From 9569519bbe933b3d33ab7ab027cde6222efe6616 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sat, 12 May 2018 11:20:14 -0700 Subject: [PATCH 08/10] TSCH: burst mode is in the standard, remove custom link option --- os/net/mac/tsch/tsch-conf.h | 11 +++-------- os/net/mac/tsch/tsch-const.h | 1 - os/net/mac/tsch/tsch-schedule.c | 3 +-- os/net/mac/tsch/tsch-slot-operation.c | 2 +- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/os/net/mac/tsch/tsch-conf.h b/os/net/mac/tsch/tsch-conf.h index afd90aaef..8613eb0e3 100644 --- a/os/net/mac/tsch/tsch-conf.h +++ b/os/net/mac/tsch/tsch-conf.h @@ -317,14 +317,9 @@ #define TSCH_SCHEDULE_WITH_6TISCH_MINIMAL (!(BUILD_WITH_ORCHESTRA)) #endif -/* Add burst mode to 6TiSCH minimal schedule */ -#ifdef TSCH_CONF_WITH_6TISCH_MINIMAL_WITH_BURST -#define TSCH_WITH_6TISCH_MINIMAL_WITH_BURST TSCH_CONF_WITH_6TISCH_MINIMAL_WITH_BURST -#else -#define TSCH_WITH_6TISCH_MINIMAL_WITH_BURST 0 -#endif - -/* Set an upper bound on burst length */ +/* Set an upper bound on burst length. Set to 0 to never set the frame pending + * bit, i.e., never trigger a burst. Note that receiver-side support for burst + * is always enabled, as it is part of IEEE 802.1.5.4-2015 (Section 7.2.1.3)*/ #ifdef TSCH_CONF_BURST_MAX_LEN #define TSCH_BURST_MAX_LEN TSCH_CONF_BURST_MAX_LEN #else diff --git a/os/net/mac/tsch/tsch-const.h b/os/net/mac/tsch/tsch-const.h index 51e7d0625..81ca7ffa8 100644 --- a/os/net/mac/tsch/tsch-const.h +++ b/os/net/mac/tsch/tsch-const.h @@ -53,7 +53,6 @@ #define LINK_OPTION_RX 2 #define LINK_OPTION_SHARED 4 #define LINK_OPTION_TIME_KEEPING 8 -#define LINK_OPTION_BURST 16 /* Default IEEE 802.15.4e hopping sequences, obtained from https://gist.github.com/twatteyne/2e22ee3c1a802b685695 */ /* 16 channels, sequence length 16 */ diff --git a/os/net/mac/tsch/tsch-schedule.c b/os/net/mac/tsch/tsch-schedule.c index a03363eb9..4f94b8e30 100644 --- a/os/net/mac/tsch/tsch-schedule.c +++ b/os/net/mac/tsch/tsch-schedule.c @@ -423,8 +423,7 @@ tsch_schedule_create_minimal(void) * but is required according to 802.15.4e if also used for EB transmission. * Timeslot: 0, channel offset: 0. */ tsch_schedule_add_link(sf_min, - LINK_OPTION_RX | LINK_OPTION_TX | LINK_OPTION_SHARED | LINK_OPTION_TIME_KEEPING - | (TSCH_WITH_6TISCH_MINIMAL_WITH_BURST ? LINK_OPTION_BURST : 0), + (LINK_OPTION_RX | LINK_OPTION_TX | LINK_OPTION_SHARED | LINK_OPTION_TIME_KEEPING), LINK_TYPE_ADVERTISING, &tsch_broadcast_address, 0, 0); } diff --git a/os/net/mac/tsch/tsch-slot-operation.c b/os/net/mac/tsch/tsch-slot-operation.c index bc76b526e..de4dec676 100644 --- a/os/net/mac/tsch/tsch-slot-operation.c +++ b/os/net/mac/tsch/tsch-slot-operation.c @@ -477,7 +477,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) is_broadcast = current_neighbor->is_broadcast; /* Unicast. More packets in queue for the neighbor? */ burst_link_requested = 0; - if(!is_broadcast && (current_link->link_options & LINK_OPTION_BURST) + if(!is_broadcast && tsch_current_burst_count + 1 < TSCH_BURST_MAX_LEN && tsch_queue_packet_count(¤t_neighbor->addr) > 1) { burst_link_requested = 1; From 359ae59499760f17ca1bc73ac4b4da895f6056d4 Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sun, 13 May 2018 06:47:37 -0700 Subject: [PATCH 09/10] tsch-packet: define constant for frame pending bit offset --- os/net/mac/tsch/tsch-packet.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/os/net/mac/tsch/tsch-packet.c b/os/net/mac/tsch/tsch-packet.c index 5f6cb6b54..133e9a668 100644 --- a/os/net/mac/tsch/tsch-packet.c +++ b/os/net/mac/tsch/tsch-packet.c @@ -70,6 +70,9 @@ */ static struct packetbuf_attr eackbuf_attrs[PACKETBUF_NUM_ATTRS]; +/* The offset of the frame pending bit flag within the first byte of FCF */ +#define IEEE802154_FRAME_PENDING_BIT_OFFSET 4 + /*---------------------------------------------------------------------------*/ static int tsch_packet_eackbuf_set_attr(uint8_t type, const packetbuf_attr_t val) @@ -463,14 +466,14 @@ tsch_packet_parse_eb(const uint8_t *buf, int buf_size, void tsch_packet_set_frame_pending(uint8_t *buf, int buf_size) { - buf[0] |= (1 << 4); + buf[0] |= (1 << IEEE802154_FRAME_PENDING_BIT_OFFSET); } /*---------------------------------------------------------------------------*/ /* Get frame pending bit from a packet */ int tsch_packet_get_frame_pending(uint8_t *buf, int buf_size) { - return (buf[0] >> 4) & 1; + return (buf[0] >> IEEE802154_FRAME_PENDING_BIT_OFFSET) & 1; } /*---------------------------------------------------------------------------*/ /** @} */ From 2bf79a98ce9727c2c547b4ba3ed0bcea1778d3ef Mon Sep 17 00:00:00 2001 From: Simon Duquennoy Date: Sun, 13 May 2018 06:49:52 -0700 Subject: [PATCH 10/10] TSCH burst mode: remove unnecessary variable burst_tsch_current_channel --- os/net/mac/tsch/tsch-slot-operation.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/os/net/mac/tsch/tsch-slot-operation.c b/os/net/mac/tsch/tsch-slot-operation.c index de4dec676..917d13816 100644 --- a/os/net/mac/tsch/tsch-slot-operation.c +++ b/os/net/mac/tsch/tsch-slot-operation.c @@ -171,8 +171,6 @@ static struct tsch_neighbor *current_neighbor = NULL; static int burst_link_scheduled = 0; /* Counts the length of the current burst */ int tsch_current_burst_count = 0; -/* The physical channel of the current burst */ -static uint16_t burst_tsch_current_channel = 0; /* Protothread for association */ PT_THREAD(tsch_scan(struct pt *pt)); @@ -969,7 +967,7 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr)) /* If we are in a burst, we stick to current channel instead of * doing channel hopping, as per IEEE 802.15.4-2015 */ if(burst_link_scheduled) { - tsch_current_channel = burst_tsch_current_channel; + /* Reset burst_link_scheduled flag. Will be set again if burst continue. */ burst_link_scheduled = 0; } else { /* Hop channel */ @@ -1034,7 +1032,6 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr)) next time offset */ if(burst_link_scheduled) { timeslot_diff = 1; - burst_tsch_current_channel = tsch_current_channel; backup_link = NULL; /* Keep track of the number of repetitions */ tsch_current_burst_count++;