From 667dd6a21084943a545e322c5ca91aebe3187926 Mon Sep 17 00:00:00 2001 From: Yasuyuki Tanaka Date: Wed, 14 Dec 2016 16:50:28 +0100 Subject: [PATCH 1/6] TSCH: put tsch_ prefix to definitions in the global scope struct asn_t -> struct tsch_asn_t struct asn_divisor_t -> tsch_asn_divisor_t ASN_ macros -> TSCH_ASN_ macros current_asn -> tsch_current_asn --- core/net/mac/frame802154e-ie.h | 2 +- core/net/mac/tsch/tsch-asn.h | 16 +++---- core/net/mac/tsch/tsch-log.c | 2 +- core/net/mac/tsch/tsch-log.h | 2 +- core/net/mac/tsch/tsch-packet.c | 2 +- core/net/mac/tsch/tsch-private.h | 4 +- core/net/mac/tsch/tsch-schedule.c | 6 +-- core/net/mac/tsch/tsch-schedule.h | 4 +- core/net/mac/tsch/tsch-security.c | 7 +-- core/net/mac/tsch/tsch-security.h | 4 +- core/net/mac/tsch/tsch-slot-operation.c | 44 +++++++++---------- core/net/mac/tsch/tsch-slot-operation.h | 6 +-- core/net/mac/tsch/tsch.c | 32 +++++++------- .../tsch/simple-sensor-network/node/node.c | 2 +- 14 files changed, 67 insertions(+), 66 deletions(-) diff --git a/core/net/mac/frame802154e-ie.h b/core/net/mac/frame802154e-ie.h index d6747557c..bc6be3444 100644 --- a/core/net/mac/frame802154e-ie.h +++ b/core/net/mac/frame802154e-ie.h @@ -70,7 +70,7 @@ struct ieee802154_ies { uint16_t ie_mlme_len; /* Payload Short MLME IEs */ uint8_t ie_tsch_synchronization_offset; - struct asn_t ie_asn; + struct tsch_asn_t ie_asn; uint8_t ie_join_priority; uint8_t ie_tsch_timeslot_id; uint16_t ie_tsch_timeslot[tsch_ts_elements_count]; diff --git a/core/net/mac/tsch/tsch-asn.h b/core/net/mac/tsch/tsch-asn.h index 53f7582d4..14802b8d7 100644 --- a/core/net/mac/tsch/tsch-asn.h +++ b/core/net/mac/tsch/tsch-asn.h @@ -44,13 +44,13 @@ /************ Types ***********/ /* The ASN is an absolute slot number over 5 bytes. */ -struct asn_t { +struct tsch_asn_t { uint32_t ls4b; /* least significant 4 bytes */ uint8_t ms1b; /* most significant 1 byte */ }; /* For quick modulo operation on ASN */ -struct asn_divisor_t { +struct tsch_asn_divisor_t { uint16_t val; /* Divisor value */ uint16_t asn_ms1b_remainder; /* Remainder of the operation 0x100000000 / val */ }; @@ -58,38 +58,38 @@ struct asn_divisor_t { /************ Macros **********/ /* Initialize ASN */ -#define ASN_INIT(asn, ms1b_, ls4b_) do { \ +#define TSCH_ASN_INIT(asn, ms1b_, ls4b_) do { \ (asn).ms1b = (ms1b_); \ (asn).ls4b = (ls4b_); \ } while(0); /* Increment an ASN by inc (32 bits) */ -#define ASN_INC(asn, inc) do { \ +#define TSCH_ASN_INC(asn, inc) do { \ uint32_t new_ls4b = (asn).ls4b + (inc); \ if(new_ls4b < (asn).ls4b) { (asn).ms1b++; } \ (asn).ls4b = new_ls4b; \ } while(0); /* Decrement an ASN by inc (32 bits) */ -#define ASN_DEC(asn, dec) do { \ +#define TSCH_ASN_DEC(asn, dec) do { \ uint32_t new_ls4b = (asn).ls4b - (dec); \ if(new_ls4b > (asn).ls4b) { (asn).ms1b--; } \ (asn).ls4b = new_ls4b; \ } while(0); /* Returns the 32-bit diff between asn1 and asn2 */ -#define ASN_DIFF(asn1, asn2) \ +#define TSCH_ASN_DIFF(asn1, asn2) \ ((asn1).ls4b - (asn2).ls4b) /* Initialize a struct asn_divisor_t */ -#define ASN_DIVISOR_INIT(div, val_) do { \ +#define TSCH_ASN_DIVISOR_INIT(div, val_) do { \ (div).val = (val_); \ (div).asn_ms1b_remainder = ((0xffffffff % (val_)) + 1) % (val_); \ } while(0); /* Returns the result (16 bits) of a modulo operation on ASN, * with divisor being a struct asn_divisor_t */ -#define ASN_MOD(asn, div) \ +#define TSCH_ASN_MOD(asn, div) \ ((uint16_t)((asn).ls4b % (div).val) \ + (uint16_t)((asn).ms1b * (div).asn_ms1b_remainder % (div).val)) \ % (div).val diff --git a/core/net/mac/tsch/tsch-log.c b/core/net/mac/tsch/tsch-log.c index 8ab23215b..c8d52a2e6 100644 --- a/core/net/mac/tsch/tsch-log.c +++ b/core/net/mac/tsch/tsch-log.c @@ -132,7 +132,7 @@ tsch_log_prepare_add(void) int log_index = ringbufindex_peek_put(&log_ringbuf); if(log_index != -1) { struct tsch_log_t *log = &log_array[log_index]; - log->asn = current_asn; + log->asn = tsch_current_asn; log->link = current_link; return log; } else { diff --git a/core/net/mac/tsch/tsch-log.h b/core/net/mac/tsch/tsch-log.h index 9b8032577..bdd71090c 100644 --- a/core/net/mac/tsch/tsch-log.h +++ b/core/net/mac/tsch/tsch-log.h @@ -81,7 +81,7 @@ struct tsch_log_t { tsch_log_rx, tsch_log_message } type; - struct asn_t asn; + struct tsch_asn_t asn; struct tsch_link *link; union { char message[48]; diff --git a/core/net/mac/tsch/tsch-packet.c b/core/net/mac/tsch/tsch-packet.c index 100a4ccde..b0ee33535 100644 --- a/core/net/mac/tsch/tsch-packet.c +++ b/core/net/mac/tsch/tsch-packet.c @@ -338,7 +338,7 @@ int tsch_packet_update_eb(uint8_t *buf, int buf_size, uint8_t tsch_sync_ie_offset) { struct ieee802154_ies ies; - ies.ie_asn = current_asn; + ies.ie_asn = tsch_current_asn; ies.ie_join_priority = tsch_join_priority; frame80215e_create_ie_tsch_synchronization(buf+tsch_sync_ie_offset, buf_size-tsch_sync_ie_offset, &ies); return 1; diff --git a/core/net/mac/tsch/tsch-private.h b/core/net/mac/tsch/tsch-private.h index 44c928ae7..9234e677a 100644 --- a/core/net/mac/tsch/tsch-private.h +++ b/core/net/mac/tsch/tsch-private.h @@ -80,12 +80,12 @@ extern const linkaddr_t tsch_broadcast_address; /* The address we use to identify EB queue */ extern const linkaddr_t tsch_eb_address; /* The current Absolute Slot Number (ASN) */ -extern struct asn_t current_asn; +extern struct tsch_asn_t tsch_current_asn; extern uint8_t tsch_join_priority; extern struct tsch_link *current_link; /* TSCH channel hopping sequence */ extern uint8_t tsch_hopping_sequence[TSCH_HOPPING_SEQUENCE_MAX_LEN]; -extern struct asn_divisor_t tsch_hopping_sequence_length; +extern struct tsch_asn_divisor_t tsch_hopping_sequence_length; /* TSCH timeslot timing (in rtimer ticks) */ extern rtimer_clock_t tsch_timing[tsch_ts_elements_count]; diff --git a/core/net/mac/tsch/tsch-schedule.c b/core/net/mac/tsch/tsch-schedule.c index 0a61b5f12..0bb1355ae 100644 --- a/core/net/mac/tsch/tsch-schedule.c +++ b/core/net/mac/tsch/tsch-schedule.c @@ -87,7 +87,7 @@ tsch_schedule_add_slotframe(uint16_t handle, uint16_t size) if(sf != NULL) { /* Initialize the slotframe */ sf->handle = handle; - ASN_DIVISOR_INIT(sf->size, size); + TSCH_ASN_DIVISOR_INIT(sf->size, size); LIST_STRUCT_INIT(sf, links_list); /* Add the slotframe to the global list */ list_add(slotframe_list, sf); @@ -310,7 +310,7 @@ tsch_schedule_get_link_by_timeslot(struct tsch_slotframe *slotframe, uint16_t ti /*---------------------------------------------------------------------------*/ /* Returns the next active link after a given ASN, and a backup link (for the same ASN, with Rx flag) */ struct tsch_link * -tsch_schedule_get_next_active_link(struct asn_t *asn, uint16_t *time_offset, +tsch_schedule_get_next_active_link(struct tsch_asn_t *asn, uint16_t *time_offset, struct tsch_link **backup_link) { uint16_t time_to_curr_best = 0; @@ -324,7 +324,7 @@ tsch_schedule_get_next_active_link(struct asn_t *asn, uint16_t *time_offset, /* For each slotframe, look for the earliest occurring link */ while(sf != NULL) { /* Get timeslot from ASN, given the slotframe length */ - uint16_t timeslot = ASN_MOD(*asn, sf->size); + uint16_t timeslot = TSCH_ASN_MOD(*asn, sf->size); struct tsch_link *l = list_head(sf->links_list); while(l != NULL) { uint16_t time_to_timeslot = diff --git a/core/net/mac/tsch/tsch-schedule.h b/core/net/mac/tsch/tsch-schedule.h index 7b8af2801..75f757e66 100644 --- a/core/net/mac/tsch/tsch-schedule.h +++ b/core/net/mac/tsch/tsch-schedule.h @@ -119,7 +119,7 @@ struct tsch_slotframe { uint16_t handle; /* Number of timeslots in the slotframe. * Stored as struct asn_divisor_t because we often need ASN%size */ - struct asn_divisor_t size; + struct tsch_asn_divisor_t size; /* List of links belonging to this slotframe */ LIST_STRUCT(links_list); }; @@ -158,7 +158,7 @@ int tsch_schedule_remove_link(struct tsch_slotframe *slotframe, struct tsch_link int tsch_schedule_remove_link_by_timeslot(struct tsch_slotframe *slotframe, uint16_t timeslot); /* Returns the next active link after a given ASN, and a backup link (for the same ASN, with Rx flag) */ -struct tsch_link * tsch_schedule_get_next_active_link(struct asn_t *asn, uint16_t *time_offset, +struct tsch_link * tsch_schedule_get_next_active_link(struct tsch_asn_t *asn, uint16_t *time_offset, struct tsch_link **backup_link); #endif /* __TSCH_SCHEDULE_H__ */ diff --git a/core/net/mac/tsch/tsch-security.c b/core/net/mac/tsch/tsch-security.c index 59abaf2cf..0a3d19b8f 100644 --- a/core/net/mac/tsch/tsch-security.c +++ b/core/net/mac/tsch/tsch-security.c @@ -73,7 +73,7 @@ static aes_key keys[] = { /*---------------------------------------------------------------------------*/ static void tsch_security_init_nonce(uint8_t *nonce, - const linkaddr_t *sender, struct asn_t *asn) + const linkaddr_t *sender, struct tsch_asn_t *asn) { memcpy(nonce, sender, 8); nonce[8] = asn->ms1b; @@ -137,7 +137,7 @@ tsch_security_mic_len(const frame802154_t *frame) /*---------------------------------------------------------------------------*/ unsigned int tsch_security_secure_frame(uint8_t *hdr, uint8_t *outbuf, - int hdrlen, int datalen, struct asn_t *asn) + int hdrlen, int datalen, struct tsch_asn_t *asn) { frame802154_t frame; uint8_t key_index = 0; @@ -200,7 +200,8 @@ tsch_security_secure_frame(uint8_t *hdr, uint8_t *outbuf, /*---------------------------------------------------------------------------*/ unsigned int tsch_security_parse_frame(const uint8_t *hdr, int hdrlen, int datalen, - const frame802154_t *frame, const linkaddr_t *sender, struct asn_t *asn) + const frame802154_t *frame, const linkaddr_t *sender, + struct tsch_asn_t *asn) { uint8_t generated_mic[16]; uint8_t key_index = 0; diff --git a/core/net/mac/tsch/tsch-security.h b/core/net/mac/tsch/tsch-security.h index 3d6e9bf78..d7fa29f51 100644 --- a/core/net/mac/tsch/tsch-security.h +++ b/core/net/mac/tsch/tsch-security.h @@ -130,7 +130,7 @@ unsigned int tsch_security_mic_len(const frame802154_t *frame); */ unsigned int tsch_security_secure_frame(uint8_t *hdr, uint8_t *outbuf, int hdrlen, int datalen, - struct asn_t *asn); + struct tsch_asn_t *asn); /** * \brief Parse and check a frame protected with encryption and/or MIC @@ -140,6 +140,6 @@ unsigned int tsch_security_secure_frame(uint8_t *hdr, uint8_t *outbuf, unsigned int tsch_security_parse_frame(const uint8_t *hdr, int hdrlen, int datalen, const frame802154_t *frame, const linkaddr_t *sender, - struct asn_t *asn); + struct tsch_asn_t *asn); #endif /* __TSCH_SECURITY_H__ */ diff --git a/core/net/mac/tsch/tsch-slot-operation.c b/core/net/mac/tsch/tsch-slot-operation.c index 90e0fcad0..e4be26654 100644 --- a/core/net/mac/tsch/tsch-slot-operation.c +++ b/core/net/mac/tsch/tsch-slot-operation.c @@ -139,7 +139,7 @@ struct ringbufindex input_ringbuf; struct input_packet input_array[TSCH_MAX_INCOMING_PACKETS]; /* Last time we received Sync-IE (ACK or data packet from a time source) */ -static struct asn_t last_sync_asn; +static struct tsch_asn_t last_sync_asn; /* A global lock for manipulating data structures safely from outside of interrupt */ static volatile int tsch_locked = 0; @@ -248,9 +248,9 @@ tsch_release_lock(void) /* Return channel from ASN and channel offset */ uint8_t -tsch_calculate_channel(struct asn_t *asn, uint8_t channel_offset) +tsch_calculate_channel(struct tsch_asn_t *asn, uint8_t channel_offset) { - uint16_t index_of_0 = ASN_MOD(*asn, tsch_hopping_sequence_length); + uint16_t index_of_0 = TSCH_ASN_MOD(*asn, tsch_hopping_sequence_length); uint16_t index_of_offset = (index_of_0 + channel_offset) % tsch_hopping_sequence_length.val; return tsch_hopping_sequence[index_of_offset]; } @@ -530,7 +530,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) * the original untouched. This is to allow for future retransmissions. */ int with_encryption = queuebuf_attr(current_packet->qb, PACKETBUF_ATTR_SECURITY_LEVEL) & 0x4; packet_len += tsch_security_secure_frame(packet, with_encryption ? encrypted_packet : packet, current_packet->header_len, - packet_len - current_packet->header_len, ¤t_asn); + packet_len - current_packet->header_len, &tsch_current_asn); if(with_encryption) { packet = encrypted_packet; } @@ -627,7 +627,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) #if LLSEC802154_ENABLED if(ack_len != 0) { if(!tsch_security_parse_frame(ackbuf, ack_hdrlen, ack_len - ack_hdrlen - tsch_security_mic_len(&frame), - &frame, ¤t_neighbor->addr, ¤t_asn)) { + &frame, ¤t_neighbor->addr, &tsch_current_asn)) { TSCH_LOG_ADD(tsch_log_message, snprintf(log->message, sizeof(log->message), "!failed to authenticate ACK")); @@ -644,7 +644,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) if(ack_len != 0) { if(is_time_source) { int32_t eack_time_correction = US_TO_RTIMERTICKS(ack_ies.ie_time_correction); - int32_t since_last_timesync = ASN_DIFF(current_asn, last_sync_asn); + int32_t since_last_timesync = TSCH_ASN_DIFF(tsch_current_asn, last_sync_asn); if(eack_time_correction > SYNC_IE_BOUND) { drift_correction = SYNC_IE_BOUND; } else if(eack_time_correction < -SYNC_IE_BOUND) { @@ -661,7 +661,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t)) is_drift_correction_used = 1; tsch_timesync_update(current_neighbor, since_last_timesync, drift_correction); /* Keep track of sync time */ - last_sync_asn = current_asn; + last_sync_asn = tsch_current_asn; tsch_schedule_keepalive(); } mac_tx_status = MAC_TX_OK; @@ -793,7 +793,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)) /* Read packet */ current_input->len = NETSTACK_RADIO.read((void *)current_input->payload, TSCH_PACKET_MAX_LEN); NETSTACK_RADIO.get_value(RADIO_PARAM_LAST_RSSI, &radio_last_rssi); - current_input->rx_asn = current_asn; + current_input->rx_asn = tsch_current_asn; current_input->rssi = (signed)radio_last_rssi; current_input->channel = current_channel; header_len = frame802154_parse((uint8_t *)current_input->payload, current_input->len, &frame); @@ -813,7 +813,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)) if(frame_valid) { if(tsch_security_parse_frame( current_input->payload, header_len, current_input->len - header_len - tsch_security_mic_len(&frame), - &frame, &source_address, ¤t_asn)) { + &frame, &source_address, &tsch_current_asn)) { current_input->len -= tsch_security_mic_len(&frame); } else { TSCH_LOG_ADD(tsch_log_message, @@ -864,7 +864,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)) #if LLSEC802154_ENABLED if(tsch_is_pan_secured) { /* Secure ACK frame. There is only header and header IEs, therefore data len == 0. */ - ack_len += tsch_security_secure_frame(ack_buf, ack_buf, ack_len, 0, ¤t_asn); + ack_len += tsch_security_secure_frame(ack_buf, ack_buf, ack_len, 0, &tsch_current_asn); } #endif /* LLSEC802154_ENABLED */ @@ -882,9 +882,9 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)) /* If the sender is a time source, proceed to clock drift compensation */ n = tsch_queue_get_nbr(&source_address); if(n != NULL && n->is_time_source) { - int32_t since_last_timesync = ASN_DIFF(current_asn, last_sync_asn); + int32_t since_last_timesync = TSCH_ASN_DIFF(tsch_current_asn, last_sync_asn); /* Keep track of last sync time */ - last_sync_asn = current_asn; + last_sync_asn = tsch_current_asn; /* Save estimated drift */ drift_correction = -estimated_drift; is_drift_correction_used = 1; @@ -970,7 +970,7 @@ 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(¤t_asn, current_link->channel_offset); + 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); @@ -996,12 +996,12 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr)) /* End of slot operation, schedule next slot or resynchronize */ /* Do we need to resynchronize? i.e., wait for EB again */ - if(!tsch_is_coordinator && (ASN_DIFF(current_asn, last_sync_asn) > + if(!tsch_is_coordinator && (TSCH_ASN_DIFF(tsch_current_asn, last_sync_asn) > (100 * TSCH_CLOCK_TO_SLOTS(TSCH_DESYNC_THRESHOLD / 100, tsch_timing[tsch_ts_timeslot_length])))) { TSCH_LOG_ADD(tsch_log_message, snprintf(log->message, sizeof(log->message), "! leaving the network, last sync %u", - (unsigned)ASN_DIFF(current_asn, last_sync_asn)); + (unsigned)TSCH_ASN_DIFF(tsch_current_asn, last_sync_asn)); ); last_timesource_neighbor = NULL; tsch_disassociate(); @@ -1023,14 +1023,14 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr)) } /* Get next active link */ - current_link = tsch_schedule_get_next_active_link(¤t_asn, ×lot_diff, &backup_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; } /* Update ASN */ - ASN_INC(current_asn, timeslot_diff); + TSCH_ASN_INC(tsch_current_asn, timeslot_diff); /* Time to next wake up */ time_to_next_active_slot = timeslot_diff * tsch_timing[tsch_ts_timeslot_length] + drift_correction; drift_correction = 0; @@ -1061,14 +1061,14 @@ tsch_slot_operation_start(void) do { uint16_t timeslot_diff; /* Get next active link */ - current_link = tsch_schedule_get_next_active_link(¤t_asn, ×lot_diff, &backup_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; } /* Update ASN */ - ASN_INC(current_asn, timeslot_diff); + TSCH_ASN_INC(tsch_current_asn, timeslot_diff); /* Time to next wake up */ time_to_next_active_slot = timeslot_diff * tsch_timing[tsch_ts_timeslot_length]; /* Update current slot start */ @@ -1080,11 +1080,11 @@ tsch_slot_operation_start(void) /* Start actual slot operation */ void tsch_slot_operation_sync(rtimer_clock_t next_slot_start, - struct asn_t *next_slot_asn) + struct tsch_asn_t *next_slot_asn) { current_slot_start = next_slot_start; - current_asn = *next_slot_asn; - last_sync_asn = current_asn; + tsch_current_asn = *next_slot_asn; + last_sync_asn = tsch_current_asn; current_link = NULL; } /*---------------------------------------------------------------------------*/ diff --git a/core/net/mac/tsch/tsch-slot-operation.h b/core/net/mac/tsch/tsch-slot-operation.h index ec05d8736..c6af61ce2 100644 --- a/core/net/mac/tsch/tsch-slot-operation.h +++ b/core/net/mac/tsch/tsch-slot-operation.h @@ -87,7 +87,7 @@ int TSCH_CALLBACK_DO_NACK(struct tsch_link *link, linkaddr_t *src, linkaddr_t *d /* Stores data about an incoming packet */ struct input_packet { uint8_t payload[TSCH_PACKET_MAX_LEN]; /* Packet payload */ - struct asn_t rx_asn; /* ASN when the packet was received */ + struct tsch_asn_t rx_asn; /* ASN when the packet was received */ int len; /* Packet len */ int16_t rssi; /* RSSI for this packet */ uint8_t channel; /* Channel we received the packet on */ @@ -107,7 +107,7 @@ extern struct input_packet input_array[TSCH_MAX_INCOMING_PACKETS]; /********** Functions *********/ /* Returns a 802.15.4 channel from an ASN and channel offset */ -uint8_t tsch_calculate_channel(struct asn_t *asn, uint8_t channel_offset); +uint8_t tsch_calculate_channel(struct tsch_asn_t *asn, uint8_t channel_offset); /* Is TSCH locked? */ int tsch_is_locked(void); /* Lock TSCH (no link operation) */ @@ -117,7 +117,7 @@ void tsch_release_lock(void); /* Set global time before starting slot operation, * with a rtimer time and an ASN */ void tsch_slot_operation_sync(rtimer_clock_t next_slot_start, - struct asn_t *next_slot_asn); + struct tsch_asn_t *next_slot_asn); /* Start actual slot operation */ void tsch_slot_operation_start(void); diff --git a/core/net/mac/tsch/tsch.c b/core/net/mac/tsch/tsch.c index 348406dac..d82453f4f 100644 --- a/core/net/mac/tsch/tsch.c +++ b/core/net/mac/tsch/tsch.c @@ -90,7 +90,7 @@ NBR_TABLE(struct eb_stat, eb_stats); /* TSCH channel hopping sequence */ uint8_t tsch_hopping_sequence[TSCH_HOPPING_SEQUENCE_MAX_LEN]; -struct asn_divisor_t tsch_hopping_sequence_length; +struct tsch_asn_divisor_t tsch_hopping_sequence_length; /* Default TSCH timeslot timing (in micro-second) */ static const uint16_t tsch_default_timing_us[tsch_ts_elements_count] = { @@ -131,7 +131,7 @@ int tsch_is_associated = 0; /* Is the PAN running link-layer security? */ int tsch_is_pan_secured = LLSEC802154_ENABLED; /* The current Absolute Slot Number (ASN) */ -struct asn_t current_asn; +struct tsch_asn_t tsch_current_asn; /* Device rank or join priority: * For PAN coordinator: 0 -- lower is better */ uint8_t tsch_join_priority; @@ -202,7 +202,7 @@ tsch_reset(void) tsch_queue_update_time_source(NULL); /* Initialize global variables */ tsch_join_priority = 0xff; - ASN_INIT(current_asn, 0, 0); + TSCH_ASN_INIT(tsch_current_asn, 0, 0); current_link = NULL; /* Reset timeslot timing to defaults */ for(i = 0; i < tsch_ts_elements_count; i++) { @@ -310,7 +310,7 @@ eb_input(struct input_packet *current_input) /* Did the EB come from our time source? */ if(n != NULL && linkaddr_cmp((linkaddr_t *)&frame.src_addr, &n->addr)) { /* Check for ASN drift */ - int32_t asn_diff = ASN_DIFF(current_input->rx_asn, eb_ies.ie_asn); + int32_t asn_diff = TSCH_ASN_DIFF(current_input->rx_asn, eb_ies.ie_asn); if(asn_diff != 0) { /* We disagree with our time source's ASN -- leave the network */ PRINTF("TSCH:! ASN drifted by %ld, leaving the network\n", asn_diff); @@ -401,7 +401,7 @@ tsch_start_coordinator(void) frame802154_set_pan_id(IEEE802154_PANID); /* Initialize hopping sequence as default */ memcpy(tsch_hopping_sequence, TSCH_DEFAULT_HOPPING_SEQUENCE, sizeof(TSCH_DEFAULT_HOPPING_SEQUENCE)); - ASN_DIVISOR_INIT(tsch_hopping_sequence_length, sizeof(TSCH_DEFAULT_HOPPING_SEQUENCE)); + TSCH_ASN_DIVISOR_INIT(tsch_hopping_sequence_length, sizeof(TSCH_DEFAULT_HOPPING_SEQUENCE)); #if TSCH_SCHEDULE_WITH_6TISCH_MINIMAL tsch_schedule_create_minimal(); #endif @@ -410,10 +410,10 @@ tsch_start_coordinator(void) tsch_join_priority = 0; PRINTF("TSCH: starting as coordinator, PAN ID %x, asn-%x.%lx\n", - frame802154_get_pan_id(), current_asn.ms1b, current_asn.ls4b); + frame802154_get_pan_id(), tsch_current_asn.ms1b, tsch_current_asn.ls4b); /* Start slot operation */ - tsch_slot_operation_sync(RTIMER_NOW(), ¤t_asn); + tsch_slot_operation_sync(RTIMER_NOW(), &tsch_current_asn); } /*---------------------------------------------------------------------------*/ /* Leave the TSCH network */ @@ -442,7 +442,7 @@ tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp) return 0; } - current_asn = ies.ie_asn; + tsch_current_asn = ies.ie_asn; tsch_join_priority = ies.ie_join_priority + 1; #if TSCH_JOIN_SECURED_ONLY @@ -455,7 +455,7 @@ tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp) #if LLSEC802154_ENABLED if(!tsch_security_parse_frame(input_eb->payload, hdrlen, input_eb->len - hdrlen - tsch_security_mic_len(&frame), - &frame, (linkaddr_t*)&frame.src_addr, ¤t_asn)) { + &frame, (linkaddr_t*)&frame.src_addr, &tsch_current_asn)) { PRINTF("TSCH:! parse_eb: failed to authenticate\n"); return 0; } @@ -494,11 +494,11 @@ tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp) /* TSCH hopping sequence */ if(ies.ie_channel_hopping_sequence_id == 0) { memcpy(tsch_hopping_sequence, TSCH_DEFAULT_HOPPING_SEQUENCE, sizeof(TSCH_DEFAULT_HOPPING_SEQUENCE)); - ASN_DIVISOR_INIT(tsch_hopping_sequence_length, sizeof(TSCH_DEFAULT_HOPPING_SEQUENCE)); + TSCH_ASN_DIVISOR_INIT(tsch_hopping_sequence_length, sizeof(TSCH_DEFAULT_HOPPING_SEQUENCE)); } else { if(ies.ie_hopping_sequence_len <= sizeof(tsch_hopping_sequence)) { memcpy(tsch_hopping_sequence, ies.ie_hopping_sequence_list, ies.ie_hopping_sequence_len); - ASN_DIVISOR_INIT(tsch_hopping_sequence_length, ies.ie_hopping_sequence_len); + TSCH_ASN_DIVISOR_INIT(tsch_hopping_sequence_length, ies.ie_hopping_sequence_len); } else { PRINTF("TSCH:! parse_eb: hopping sequence too long (%u)\n", ies.ie_hopping_sequence_len); return 0; @@ -509,10 +509,10 @@ tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp) /* Divide by 4k and multiply again to avoid integer overflow */ uint32_t expected_asn = 4096 * TSCH_CLOCK_TO_SLOTS(clock_time() / 4096, tsch_timing_timeslot_length); /* Expected ASN based on our current time*/ int32_t asn_threshold = TSCH_CHECK_TIME_AT_ASSOCIATION * 60ul * TSCH_CLOCK_TO_SLOTS(CLOCK_SECOND, tsch_timing_timeslot_length); - int32_t asn_diff = (int32_t)current_asn.ls4b - expected_asn; + int32_t asn_diff = (int32_t)tsch_current_asn.ls4b - expected_asn; if(asn_diff > asn_threshold) { PRINTF("TSCH:! EB ASN rejected %lx %lx %ld\n", - current_asn.ls4b, expected_asn, asn_diff); + tsch_current_asn.ls4b, expected_asn, asn_diff); return 0; } #endif @@ -562,7 +562,7 @@ tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp) frame802154_set_pan_id(frame.src_pid); /* Synchronize on EB */ - tsch_slot_operation_sync(timestamp - tsch_timing[tsch_ts_tx_offset], ¤t_asn); + tsch_slot_operation_sync(timestamp - tsch_timing[tsch_ts_tx_offset], &tsch_current_asn); /* Update global flags */ tsch_is_associated = 1; @@ -578,7 +578,7 @@ tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp) PRINTF("TSCH: association done, sec %u, PAN ID %x, asn-%x.%lx, jp %u, timeslot id %u, hopping id %u, slotframe len %u with %u links, from ", tsch_is_pan_secured, frame.src_pid, - current_asn.ms1b, current_asn.ls4b, tsch_join_priority, + tsch_current_asn.ms1b, tsch_current_asn.ls4b, tsch_join_priority, ies.ie_tsch_timeslot_id, ies.ie_channel_hopping_sequence_id, ies.ie_tsch_slotframe_and_link.slotframe_size, @@ -609,7 +609,7 @@ PT_THREAD(tsch_scan(struct pt *pt)) /* Time when we started scanning on current_channel */ static clock_time_t current_channel_since; - ASN_INIT(current_asn, 0, 0); + TSCH_ASN_INIT(tsch_current_asn, 0, 0); etimer_set(&scan_timer, CLOCK_SECOND / TSCH_ASSOCIATION_POLL_FREQUENCY); current_channel_since = clock_time(); diff --git a/examples/jn516x/tsch/simple-sensor-network/node/node.c b/examples/jn516x/tsch/simple-sensor-network/node/node.c index 561df6a47..bb3d3456a 100644 --- a/examples/jn516x/tsch/simple-sensor-network/node/node.c +++ b/examples/jn516x/tsch/simple-sensor-network/node/node.c @@ -201,7 +201,7 @@ PROCESS_THREAD(node_process, ev, data) if (host_found) { /* Make sample count dependent on asn. After a disconnect, waveforms remain synchronous. Use node_mac to create phase offset between waveforms in different nodes */ - sample_count = ((current_asn.ls4b/((1000/(TSCH_CONF_DEFAULT_TIMESLOT_LENGTH/1000)))/INTERVAL)+node_mac[7]) % (SIZE_OF_WAVEFORM-1); + sample_count = ((tsch_current_asn.ls4b/((1000/(TSCH_CONF_DEFAULT_TIMESLOT_LENGTH/1000)))/INTERVAL)+node_mac[7]) % (SIZE_OF_WAVEFORM-1); printf("%d sec. waveform=%s. cnt=%d. value=%d\n", total_time, waveform_table[selected_waveform].str, sample_count, waveform_table[selected_waveform].table[sample_count]); my_sprintf(udp_buf, waveform_table[selected_waveform].table[sample_count]); uip_udp_packet_send(udp_conn_tx, udp_buf, strlen(udp_buf)); From 0b81c0de184ef9deab3f79317c8bf6ec70ccce16 Mon Sep 17 00:00:00 2001 From: Yasuyuki Tanaka Date: Wed, 14 Dec 2016 16:50:28 +0100 Subject: [PATCH 2/6] TSCH: make *dest_addr const (tsch_packet_create_eack) --- core/net/mac/tsch/tsch-packet.c | 2 +- core/net/mac/tsch/tsch-packet.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/net/mac/tsch/tsch-packet.c b/core/net/mac/tsch/tsch-packet.c index b0ee33535..49f954954 100644 --- a/core/net/mac/tsch/tsch-packet.c +++ b/core/net/mac/tsch/tsch-packet.c @@ -66,7 +66,7 @@ /* Construct enhanced ACK packet and return ACK length */ int tsch_packet_create_eack(uint8_t *buf, int buf_size, - linkaddr_t *dest_addr, uint8_t seqno, int16_t drift, int nack) + const linkaddr_t *dest_addr, uint8_t seqno, int16_t drift, int nack) { int ret; uint8_t curr_len = 0; diff --git a/core/net/mac/tsch/tsch-packet.h b/core/net/mac/tsch/tsch-packet.h index e974230e5..4707b2543 100644 --- a/core/net/mac/tsch/tsch-packet.h +++ b/core/net/mac/tsch/tsch-packet.h @@ -88,7 +88,7 @@ by default, useful in case of duplicate seqno */ /* Construct enhanced ACK packet and return ACK length */ int tsch_packet_create_eack(uint8_t *buf, int buf_size, - linkaddr_t *dest_addr, uint8_t seqno, int16_t drift, int nack); + const linkaddr_t *dest_addr, uint8_t seqno, int16_t drift, int nack); /* Parse enhanced ACK packet, extract drift and nack */ 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); From 35a17012360125e989850fedd721a65bb3764768 Mon Sep 17 00:00:00 2001 From: Yasuyuki Tanaka Date: Wed, 14 Dec 2016 16:50:28 +0100 Subject: [PATCH 3/6] TSCH: handle error cases returning -1 properly - tsch_send_eb_process() in tsch-slot-operation.c - tsch_rx_slot() in tsch.c --- core/net/mac/tsch/tsch-slot-operation.c | 26 +++++++++++++------------ core/net/mac/tsch/tsch.c | 2 +- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/core/net/mac/tsch/tsch-slot-operation.c b/core/net/mac/tsch/tsch-slot-operation.c index e4be26654..de7890731 100644 --- a/core/net/mac/tsch/tsch-slot-operation.c +++ b/core/net/mac/tsch/tsch-slot-operation.c @@ -861,22 +861,24 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t)) ack_len = tsch_packet_create_eack(ack_buf, sizeof(ack_buf), &source_address, frame.seq, (int16_t)RTIMERTICKS_TO_US(estimated_drift), do_nack); + if(ack_len > 0) { #if LLSEC802154_ENABLED - if(tsch_is_pan_secured) { - /* Secure ACK frame. There is only header and header IEs, therefore data len == 0. */ - ack_len += tsch_security_secure_frame(ack_buf, ack_buf, ack_len, 0, &tsch_current_asn); - } + if(tsch_is_pan_secured) { + /* Secure ACK frame. There is only header and header IEs, therefore data len == 0. */ + ack_len += tsch_security_secure_frame(ack_buf, ack_buf, ack_len, 0, &tsch_current_asn); + } #endif /* LLSEC802154_ENABLED */ - /* Copy to radio buffer */ - NETSTACK_RADIO.prepare((const void *)ack_buf, ack_len); + /* Copy to radio buffer */ + NETSTACK_RADIO.prepare((const void *)ack_buf, ack_len); - /* Wait for time to ACK and transmit ACK */ - TSCH_SCHEDULE_AND_YIELD(pt, t, rx_start_time, - packet_duration + tsch_timing[tsch_ts_tx_ack_delay] - RADIO_DELAY_BEFORE_TX, "RxBeforeAck"); - TSCH_DEBUG_RX_EVENT(); - NETSTACK_RADIO.transmit(ack_len); - tsch_radio_off(TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT); + /* Wait for time to ACK and transmit ACK */ + TSCH_SCHEDULE_AND_YIELD(pt, t, rx_start_time, + packet_duration + tsch_timing[tsch_ts_tx_ack_delay] - RADIO_DELAY_BEFORE_TX, "RxBeforeAck"); + TSCH_DEBUG_RX_EVENT(); + NETSTACK_RADIO.transmit(ack_len); + tsch_radio_off(TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT); + } } /* If the sender is a time source, proceed to clock drift compensation */ diff --git a/core/net/mac/tsch/tsch.c b/core/net/mac/tsch/tsch.c index d82453f4f..f3e7855f0 100644 --- a/core/net/mac/tsch/tsch.c +++ b/core/net/mac/tsch/tsch.c @@ -749,7 +749,7 @@ PROCESS_THREAD(tsch_send_eb_process, ev, data) #endif /* LLSEC802154_ENABLED */ eb_len = tsch_packet_create_eb(packetbuf_dataptr(), PACKETBUF_SIZE, &hdr_len, &tsch_sync_ie_offset); - if(eb_len != 0) { + if(eb_len > 0) { struct tsch_packet *p; packetbuf_set_datalen(eb_len); /* Enqueue EB packet */ From 4069ac5262031a39e4386d3999842e55860b9acd Mon Sep 17 00:00:00 2001 From: Yasuyuki Tanaka Date: Wed, 14 Dec 2016 16:50:28 +0100 Subject: [PATCH 4/6] TSCH: add a regression test for tsch-packet.c --- .../25-ieee802154/02-tsch-packet-create.csc | 203 +++++++++ regression-tests/25-ieee802154/code/Makefile | 20 +- .../25-ieee802154/code/project-conf.h | 9 + .../25-ieee802154/code/project-tsch-conf.h | 73 ++++ .../25-ieee802154/code/test-tsch-packet.c | 386 ++++++++++++++++++ .../25-ieee802154/js/02-tsch-packet-create.js | 27 ++ 6 files changed, 715 insertions(+), 3 deletions(-) create mode 100644 regression-tests/25-ieee802154/02-tsch-packet-create.csc create mode 100644 regression-tests/25-ieee802154/code/project-tsch-conf.h create mode 100644 regression-tests/25-ieee802154/code/test-tsch-packet.c create mode 100644 regression-tests/25-ieee802154/js/02-tsch-packet-create.js diff --git a/regression-tests/25-ieee802154/02-tsch-packet-create.csc b/regression-tests/25-ieee802154/02-tsch-packet-create.csc new file mode 100644 index 000000000..cf7235f82 --- /dev/null +++ b/regression-tests/25-ieee802154/02-tsch-packet-create.csc @@ -0,0 +1,203 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + [APPS_DIR]/radiologger-headless + + My simulation + 123456 + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 0.0 + 0.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype713 + default + [CONTIKI_DIR]/regression-tests/25-ieee802154/code/test-tsch-packet.c + make TARGET=cooja clean + make TEST_CONFIG_TYPE=DEFAULT test-tsch-packet.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.contikimote.interfaces.ContikiEEPROM + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype740 + security on + [CONTIKI_DIR]/regression-tests/25-ieee802154/code/test-tsch-packet.c + make TARGET=cooja clean + make TEST_CONFIG_TYPE=SECURITY_ON test-tsch-packet.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.contikimote.interfaces.ContikiEEPROM + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype399 + all enabled + [CONTIKI_DIR]/regression-tests/25-ieee802154/code/test-tsch-packet.c + make TARGET=cooja clean + make TEST_CONFIG_TYPE=ALL_ENABLED test-tsch-packet.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.contikimote.interfaces.ContikiEEPROM + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + -49.23869609407765 + -36.33693008116223 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiEEPROM + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== + + mtype713 + + + + org.contikios.cooja.interfaces.Position + -17.772442808950224 + -36.862574776701464 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiEEPROM + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== + + mtype740 + + + + org.contikios.cooja.interfaces.Position + 14.488632230762605 + -35.15143001217301 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiEEPROM + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== + + mtype399 + + + + org.contikios.cooja.plugins.SimControl + 280 + 2 + 160 + 400 + 0 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + org.contikios.cooja.plugins.skins.AttributeVisualizerSkin + 3.714690054486387 0.0 0.0 3.714690054486387 248.5428583129116 318.25485368648356 + + 400 + 0 + 400 + 1 + 1 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONTIKI_DIR]/regression-tests/25-ieee802154/js/02-tsch-packet-create.js + true + + 495 + 1 + 525 + 185 + 162 + + + diff --git a/regression-tests/25-ieee802154/code/Makefile b/regression-tests/25-ieee802154/code/Makefile index 10f911b9a..5f82fb4a5 100644 --- a/regression-tests/25-ieee802154/code/Makefile +++ b/regression-tests/25-ieee802154/code/Makefile @@ -1,7 +1,21 @@ -all: test-panid-handling +all: test-panid-handling test-tcsh-create-packet -APPS += unit-test -CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +APPS += unit-test +MODULES += core/net/mac/tsch +CFLAGS += -D PROJECT_CONF_H=\"project-conf.h\" + +WITH_TSCH ?= 0 +TEST_CONFIG_TYPE ?= DEFAULT + +CFLAGS += -D WITH_TSCH=1 + +ifeq ($(TEST_CONFIG_TYPE), SECURITY_ON) +CFLAGS += -D WITH_SECURITY_ON=1 +endif + +ifeq ($(TEST_CONFIG_TYPE), ALL_ENABLED) +CFLAGS += -D WITH_ALL_ENABLED=1 +endif CONTIKI = ../../.. CONTIKI_WITH_IPV6 = 1 diff --git a/regression-tests/25-ieee802154/code/project-conf.h b/regression-tests/25-ieee802154/code/project-conf.h index a8bb49e15..21f67b70f 100644 --- a/regression-tests/25-ieee802154/code/project-conf.h +++ b/regression-tests/25-ieee802154/code/project-conf.h @@ -29,4 +29,13 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef _PROJECT_CONF_H_ +#define _PROJECT_CONF_H_ + #define UNIT_TEST_PRINT_FUNCTION test_print_report + +#if WITH_TSCH +#include "project-tsch-conf.h" +#endif + +#endif /* !_PROJECT_CONF_H_ */ diff --git a/regression-tests/25-ieee802154/code/project-tsch-conf.h b/regression-tests/25-ieee802154/code/project-tsch-conf.h new file mode 100644 index 000000000..a3314704a --- /dev/null +++ b/regression-tests/25-ieee802154/code/project-tsch-conf.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016, Yasuyuki Tanaka + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _PROJECT_TSCH_CONF_H +#define _PROJECT_TSCH_CONF_H + +#undef FRAME802154_CONF_VERSION +#define FRAME802154_CONF_VERSION FRAME802154_IEEE802154E_2012 + +#undef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC tschmac_driver +#undef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC nordc_driver +#undef NETSTACK_CONF_FRAMER +#define NETSTACK_CONF_FRAMER framer_802154 + + +#if WITH_SECURITY_ON +#define TEST_CONFIG_TYPE SECURITY_ON + +#undef LLSEC802154_CONF_ENABLED +#define LLSEC802154_CONF_ENABLED 1 +#undef LLSEC802154_CONF_USES_EXPLICIT_KEYS +#define LLSEC802154_CONF_USES_EXPLICIT_KEYS 1 +#undef LLSEC802154_CONF_USES_FRAME_COUNTER +#define LLSEC802154_CONF_USES_FRAME_COUNTER 0 + +#elif WITH_ALL_ENABLED +#define TEST_CONFIG_TYPE ALL_ENABLED + +#undef TSCH_PACKET_CONF_EACK_WITH_DEST_ADDR +#define TSCH_PACKET_CONF_EACK_WITH_DEST_ADDR 1 +#undef TSCH_PACKET_CONF_EACK_WITH_SRC_ADDR +#define TSCH_PACKET_CONF_EACK_WITH_SRC_ADDR 1 +#undef TSCH_PACKET_CONF_EB_WITH_TIMESLOT_TIMING +#define TSCH_PACKET_CONF_EB_WITH_TIMESLOT_TIMING 1 +#undef TSCH_PACKET_CONF_EB_WITH_HOPPING_SEQUENCE +#define TSCH_PACKET_CONF_EB_WITH_HOPPING_SEQUENCE 1 +#undef TSCH_PACKET_EB_WITH_SLOTFRAME_AND_LINK +#define TSCH_PACKET_CONF_EB_WITH_SLOTFRAME_AND_LINK 1 + +#endif + + +#endif /* !_PROJECT_TSCH_CONF_H */ diff --git a/regression-tests/25-ieee802154/code/test-tsch-packet.c b/regression-tests/25-ieee802154/code/test-tsch-packet.c new file mode 100644 index 000000000..1a79792b7 --- /dev/null +++ b/regression-tests/25-ieee802154/code/test-tsch-packet.c @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2016, Yasuyuki Tanaka + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "contiki.h" +#include "unit-test.h" +#include "net/linkaddr.h" +#include "net/mac/tsch/tsch.h" +#include "net/mac/tsch/tsch-asn.h" +#include "net/mac/tsch/tsch-packet.h" +#include "net/mac/tsch/tsch-schedule.h" + +#include +#include + + +#ifndef TEST_CONFIG_TYPE +#define TEST_CONFIG_TYPE DEFAULT +#endif + +typedef enum { SUCCESS, FAILURE } result_t; + +typedef enum { DEFAULT = 0, SECURITY_ON, ALL_ENABLED } config_type_t; + +typedef struct { + size_t len; + uint8_t buf[TSCH_PACKET_MAX_LEN]; +} frame_t; + +#define NODE1 {{ 0xc1, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }} +#define NODE2 {{ 0xc1, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }} + +/* + * The following vectors are obtained with + * examples/ipv6/rpl-tsch/rpl-tsch-z1.csc except for the enhanced beacon for + * ALL_ENABLED. The raw frame was generated with rpl-tsch-cooja.csc because + * there is an issue in TSCH Timeslot IE generated by z1 mote. + */ + +typedef struct { + linkaddr_t src; + uint64_t asn; + uint8_t hdr_len; + frame_t frame; +} eb_test_vector_t; + +static const eb_test_vector_t eb_test_vectors[] = { + { /* DEFAULT */ + NODE1, 7, 18, + { 37, { 0x00, 0xeb, 0xcd, 0xab, 0xff, 0xff, 0xcd, 0xab, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc1, + 0x00, 0x3f, 0x11, 0x88, 0x06, 0x1a, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x1c, 0x00, 0x01, + 0xc8, 0x00, 0x01, 0x1b, 0x00 } + } + }, + { /* SECURITY_ON */ + NODE1, 2, 20, + { 43, { 0x08, 0xeb, 0xcd, 0xab, 0xff, 0xff, 0xcd, 0xab, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc1, + 0x69, 0x01, 0x00, 0x3f, 0x11, 0x88, 0x06, 0x1a, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1c, + 0x00, 0x01, 0xc8, 0x00, 0x01, 0x1b, 0x00, 0x7d, + 0x3e, 0x39, 0x9a, 0x6f, 0x7b } + } + }, + { /* ALL_ENABLED */ + NODE1, 12, 18, + { 85, { 0x00, 0xeb, 0xcd, 0xab, 0xff, 0xff, 0xcd, 0xab, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc1, + 0x00, 0x3f, 0x41, 0x88, 0x06, 0x1a, 0x0c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x19, 0x1c, 0x01, 0x08, + 0x07, 0x80, 0x00, 0x48, 0x08, 0xfc, 0x03, 0x20, + 0x03, 0xe8, 0x03, 0x98, 0x08, 0x90, 0x01, 0xc0, + 0x00, 0x60, 0x09, 0xa0, 0x10, 0x10, 0x27, 0x10, + 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x0f, 0x19, 0x1a, 0x14, 0x00, + 0x00, 0x0a, 0x1b, 0x01, 0x00, 0x07, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x0f } + } + } +}; + +typedef struct { + linkaddr_t src; + linkaddr_t dest; + uint64_t asn; // used only for the SECURITY_ON case + uint8_t seqno; + uint16_t drift; + uint8_t nack; + frame_t frame; +} eack_test_vector_t; + +static const eack_test_vector_t eack_test_vectors[] = { + { /* DEFAULT */ + NODE1, NODE2, 0, 1, 214, 0, + { 17, { 0x02, 0x2e, 0x01, 0xcd, 0xab, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0xc1, 0x02, 0x0f, 0xd6, + 0x00 } + } + }, + { /* SECURITY_ON */ + NODE1, NODE2, 108, 1, 214, 0, + { 23, { 0x0a, 0x2e, 0x01, 0xcd, 0xab, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0xc1, 0x6d, 0x02, 0x02, + 0x0f, 0xd6, 0x00, 0x5e, 0x20, 0x84, 0xda } + } + }, + { /* ALL_ENABLED */ + NODE1, NODE2, 0, 1, 214, 0, + { 25, { 0x02, 0xee, 0x01, 0xcd, 0xab, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0xc1, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0xc1, 0x02, 0x0f, 0xd6, + 0x00 } + } + } +}; + +PROCESS(test_process, "tsch-packet-create test"); +AUTOSTART_PROCESSES(&test_process); + +static void +print_hex(const uint8_t *p, size_t len) +{ + int i; + for(i = 0; i < len; i++) { + printf("%02x", p[i]); + } +} + +static void +update_current_asn(uint64_t asn) +{ + tsch_current_asn.ls4b = (uint32_t)(asn & 0xffffffff); + tsch_current_asn.ms1b = (uint8_t)((asn >> 32) & 0xff); +} + +static result_t +test_create_eb(const eb_test_vector_t *v) +{ + uint8_t buf[TSCH_PACKET_MAX_LEN]; + int len; + uint8_t hdr_len; + uint8_t tsch_sync_ie_offset; + + memset(buf, 0, sizeof(buf)); + + linkaddr_copy(&linkaddr_node_addr, &v->src); + update_current_asn(v->asn); + + len = tsch_packet_create_eb(buf, sizeof(buf), + &hdr_len, &tsch_sync_ie_offset); + tsch_packet_update_eb(buf, len, tsch_sync_ie_offset); +#if WITH_SECURITY_ON + len += tsch_security_secure_frame(buf, buf, + hdr_len, len - hdr_len, + &tsch_current_asn); +#endif + + printf("%s: len=%u, hdr_len=%u, buf=", __func__, len, hdr_len); + print_hex(buf, len); + printf("\n"); + + if(len != v->frame.len || + hdr_len != v->hdr_len || + memcmp(buf, v->frame.buf, len) != 0) { + return FAILURE; + } + + return SUCCESS; +} + +static result_t +test_parse_eb(const eb_test_vector_t *v) +{ + frame802154_t frame; + struct ieee802154_ies ies; + uint8_t hdr_len; + int frame_without_mic; + int len; + uint64_t asn; + linkaddr_t src_addr; + +#if WITH_SECURITY_ON + frame_without_mic = 0; + update_current_asn(v->asn); +#else + frame_without_mic = 1; +#endif + + memset(&frame, 0, sizeof(frame)); + memset(&ies, 0, sizeof(ies)); + hdr_len = 0; + + len = tsch_packet_parse_eb(v->frame.buf, v->frame.len, &frame, &ies, &hdr_len, + frame_without_mic); + asn = ((uint64_t)ies.ie_asn.ms1b << 32) + ies.ie_asn.ls4b; + printf("%s: len=%u, hdr_len=%u, asn=%llu\n", __func__, len, hdr_len, asn); + +#if WITH_SECURITY_ON + /* adjust 'len' with the length of MIC which is included in a raw frame */ + len += tsch_security_mic_len(&frame); +#endif + + if(frame.fcf.frame_type != FRAME802154_BEACONFRAME || + frame.fcf.frame_version != FRAME802154_IEEE802154E_2012) { + return FAILURE; + } + + if(len != v->frame.len || + hdr_len != v->hdr_len || + asn != v->asn) { + return FAILURE; + } + + if(frame802154_extract_linkaddr(&frame, &src_addr, NULL) == 0|| + linkaddr_cmp(&src_addr, &v->src) == 0) { + return FAILURE; + } + + return SUCCESS; +} + +static result_t +test_create_eack(const eack_test_vector_t *v) +{ + uint8_t buf[TSCH_PACKET_MAX_LEN]; + int len; +#if WITH_SECURITY_ON + int data_len = 0; +#endif + + memset(buf, 0, sizeof(buf)); + linkaddr_copy(&linkaddr_node_addr, &v->src); + + len = tsch_packet_create_eack(buf, sizeof(buf), + &v->dest, v->seqno, v->drift, v->nack); +#if WITH_SECURITY_ON + update_current_asn(v->asn); + len += tsch_security_secure_frame(buf, buf, + len, data_len, + &tsch_current_asn); +#endif + + printf("%s: len=%u, buf=", __func__, len); + print_hex(buf, len); + printf("\n"); + + if(len != v->frame.len || + memcmp(buf, v->frame.buf, len) != 0) { + return FAILURE; + } + + return SUCCESS; +} + +static result_t +test_parse_eack(const eack_test_vector_t *v) +{ + frame802154_t frame; + struct ieee802154_ies ies; + uint8_t hdr_len; + int len; +#if TSCH_PACKET_EACK_WITH_SRC_ADDR + linkaddr_t src_addr; +#endif +#if TSCH_PACKET_EACK_WITH_DEST_ADDR + linkaddr_t dest_addr; +#endif + +#if WITH_SECURITY_ON + update_current_asn(v->asn); +#endif + + memset(&frame, 0, sizeof(frame)); + memset(&ies, 0, sizeof(ies)); + hdr_len = 0; + + linkaddr_copy(&linkaddr_node_addr, &v->dest); + len = tsch_packet_parse_eack(v->frame.buf, v->frame.len, v->seqno, + &frame, &ies, &hdr_len); + printf("%s: len=%u, seqno=%u, drift=%u, nack=%u\n", + __func__, len, frame.seq, ies.ie_time_correction, ies.ie_is_nack); + +#if WITH_SECURITY_ON + /* adjust 'len' with the length of MIC which is included in a raw frame */ + len += tsch_security_mic_len(&frame); +#endif + + if(frame.fcf.frame_type != FRAME802154_ACKFRAME || + frame.fcf.frame_version != FRAME802154_IEEE802154E_2012) { + return FAILURE; + } + + if(len != v->frame.len || + frame.seq != v->seqno || + ies.ie_time_correction != v->drift || + ies.ie_is_nack != v->nack) { + return FAILURE; + } + +#if TSCH_PACKET_EACK_WITH_SRC_ADDR + if(frame802154_extract_linkaddr(&frame, &src_addr, NULL) == 0|| + linkaddr_cmp(&src_addr, &v->src) == 0) { + return FAILURE; + } +#endif + +#if TSCH_PACKET_EACK_WITH_DEST_ADDR + if(frame802154_extract_linkaddr(&frame, NULL, &dest_addr) == 0|| + linkaddr_cmp(&dest_addr, &v->dest) == 0) { + return FAILURE; + } +#endif + + return SUCCESS; +} + +PROCESS_THREAD(test_process, ev, data) +{ + static struct etimer et; + const eb_test_vector_t *eb_v; + const eack_test_vector_t *eack_v; + + PROCESS_BEGIN(); + + tsch_set_coordinator(1); + +#if WITH_SECURITY_ON + tsch_set_pan_secured(1); +#endif + + etimer_set(&et, CLOCK_SECOND); + + /* wait for minimal schedule installed */ + while(1) { + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + if(tsch_schedule_get_link_by_handle(0) != NULL) { + break; + } + etimer_reset(&et); + } + + eb_v = &eb_test_vectors[TEST_CONFIG_TYPE]; + printf("==check-me== %s\n", + test_create_eb(eb_v) == SUCCESS ? "SUCCEEDED" : "FAILED"); + printf("==check-me== %s\n", + test_parse_eb(eb_v) == SUCCESS ? "SUCCEEDED" : "FAILED"); + + eack_v = &eack_test_vectors[TEST_CONFIG_TYPE]; + printf("==check-me== %s\n", + test_create_eack(eack_v) == SUCCESS ? "SUCCEEDED" : "FAILED"); + printf("==check-me== %s\n", + test_parse_eack(eack_v) == SUCCESS ? "SUCCEEDED" : "FAILED"); + + printf("==check-me== DONE\n"); + + PROCESS_END(); +} diff --git a/regression-tests/25-ieee802154/js/02-tsch-packet-create.js b/regression-tests/25-ieee802154/js/02-tsch-packet-create.js new file mode 100644 index 000000000..d244e13d7 --- /dev/null +++ b/regression-tests/25-ieee802154/js/02-tsch-packet-create.js @@ -0,0 +1,27 @@ +TIMEOUT(10000, log.testFailed()); + +num_of_motes = sim.getMotesCount(); + +while(true) { + YIELD(); + + log.log(time + " node-" + id + ": "+ msg + "\n"); + + if(msg.contains("=check-me=") == false) { + continue; + } + + if(msg.contains("FAILED")) { + log.testFailed(); + break; + } + + if(msg.contains("DONE")) { + num_of_motes -= 1; + if(num_of_motes == 0) { + log.testOK(); + break; + } + } + +} From 3dc74dc63222b6ee0cd56f4ae5418d96218ac5fb Mon Sep 17 00:00:00 2001 From: Yasuyuki Tanaka Date: Wed, 14 Dec 2016 16:50:28 +0100 Subject: [PATCH 5/6] TSCH: fix a wrong return value tsch_security_secure_frame() returns the length of MIC in case of success. Otherwise, it is supposed to return 0. There was one case where it returns 1 in an error handling block. --- core/net/mac/tsch/tsch-security.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/net/mac/tsch/tsch-security.c b/core/net/mac/tsch/tsch-security.c index 0a3d19b8f..d7df867f0 100644 --- a/core/net/mac/tsch/tsch-security.c +++ b/core/net/mac/tsch/tsch-security.c @@ -160,7 +160,7 @@ tsch_security_secure_frame(uint8_t *hdr, uint8_t *outbuf, if(!frame.fcf.security_enabled) { /* Security is not enabled for this frame, we're done */ - return 1; + return 0; } /* Read security key index */ From 1d5fc88ae96794a5b4eb2609f06df68967925df4 Mon Sep 17 00:00:00 2001 From: Yasuyuki Tanaka Date: Wed, 14 Dec 2016 16:50:28 +0100 Subject: [PATCH 6/6] TSCH: fix indentation in tsch-packet.c --- core/net/mac/tsch/tsch-packet.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core/net/mac/tsch/tsch-packet.c b/core/net/mac/tsch/tsch-packet.c index 49f954954..e20fc8f78 100644 --- a/core/net/mac/tsch/tsch-packet.c +++ b/core/net/mac/tsch/tsch-packet.c @@ -66,7 +66,7 @@ /* Construct enhanced ACK packet and return ACK length */ int tsch_packet_create_eack(uint8_t *buf, int buf_size, - const linkaddr_t *dest_addr, uint8_t seqno, int16_t drift, int nack) + const linkaddr_t *dest_addr, uint8_t seqno, int16_t drift, int nack) { int ret; uint8_t curr_len = 0; @@ -125,7 +125,7 @@ tsch_packet_create_eack(uint8_t *buf, int buf_size, /* Parse enhanced ACK packet, extract drift and nack */ 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) + uint8_t seqno, frame802154_t *frame, struct ieee802154_ies *ies, uint8_t *hdr_len) { uint8_t curr_len = 0; int ret; @@ -155,8 +155,8 @@ tsch_packet_parse_eack(const uint8_t *buf, int buf_size, /* Check destination address (if any) */ if(frame802154_extract_linkaddr(frame, NULL, &dest) == 0 || - (!linkaddr_cmp(&dest, &linkaddr_node_addr) - && !linkaddr_cmp(&dest, &linkaddr_null))) { + (!linkaddr_cmp(&dest, &linkaddr_node_addr) + && !linkaddr_cmp(&dest, &linkaddr_null))) { return 0; } @@ -190,7 +190,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 *hdr_len, uint8_t *tsch_sync_ie_offset) + uint8_t *hdr_len, uint8_t *tsch_sync_ie_offset) { int ret = 0; uint8_t curr_len = 0; @@ -347,7 +347,7 @@ tsch_packet_update_eb(uint8_t *buf, int buf_size, uint8_t tsch_sync_ie_offset) /* Parse a IEEE 802.15.4e TSCH Enhanced Beacon (EB) */ int tsch_packet_parse_eb(const uint8_t *buf, int buf_size, - frame802154_t *frame, struct ieee802154_ies *ies, uint8_t *hdr_len, int frame_without_mic) + frame802154_t *frame, struct ieee802154_ies *ies, uint8_t *hdr_len, int frame_without_mic) { uint8_t curr_len = 0; int ret;