Merge pull request #2002 from yatch/pr/tsch-misc-update
TSCH Miscelleneous updates
This commit is contained in:
commit
fe210b05f0
|
@ -70,7 +70,7 @@ struct ieee802154_ies {
|
||||||
uint16_t ie_mlme_len;
|
uint16_t ie_mlme_len;
|
||||||
/* Payload Short MLME IEs */
|
/* Payload Short MLME IEs */
|
||||||
uint8_t ie_tsch_synchronization_offset;
|
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_join_priority;
|
||||||
uint8_t ie_tsch_timeslot_id;
|
uint8_t ie_tsch_timeslot_id;
|
||||||
uint16_t ie_tsch_timeslot[tsch_ts_elements_count];
|
uint16_t ie_tsch_timeslot[tsch_ts_elements_count];
|
||||||
|
|
|
@ -44,13 +44,13 @@
|
||||||
/************ Types ***********/
|
/************ Types ***********/
|
||||||
|
|
||||||
/* The ASN is an absolute slot number over 5 bytes. */
|
/* The ASN is an absolute slot number over 5 bytes. */
|
||||||
struct asn_t {
|
struct tsch_asn_t {
|
||||||
uint32_t ls4b; /* least significant 4 bytes */
|
uint32_t ls4b; /* least significant 4 bytes */
|
||||||
uint8_t ms1b; /* most significant 1 byte */
|
uint8_t ms1b; /* most significant 1 byte */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* For quick modulo operation on ASN */
|
/* For quick modulo operation on ASN */
|
||||||
struct asn_divisor_t {
|
struct tsch_asn_divisor_t {
|
||||||
uint16_t val; /* Divisor value */
|
uint16_t val; /* Divisor value */
|
||||||
uint16_t asn_ms1b_remainder; /* Remainder of the operation 0x100000000 / val */
|
uint16_t asn_ms1b_remainder; /* Remainder of the operation 0x100000000 / val */
|
||||||
};
|
};
|
||||||
|
@ -58,38 +58,38 @@ struct asn_divisor_t {
|
||||||
/************ Macros **********/
|
/************ Macros **********/
|
||||||
|
|
||||||
/* Initialize ASN */
|
/* Initialize ASN */
|
||||||
#define ASN_INIT(asn, ms1b_, ls4b_) do { \
|
#define TSCH_ASN_INIT(asn, ms1b_, ls4b_) do { \
|
||||||
(asn).ms1b = (ms1b_); \
|
(asn).ms1b = (ms1b_); \
|
||||||
(asn).ls4b = (ls4b_); \
|
(asn).ls4b = (ls4b_); \
|
||||||
} while(0);
|
} while(0);
|
||||||
|
|
||||||
/* Increment an ASN by inc (32 bits) */
|
/* 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); \
|
uint32_t new_ls4b = (asn).ls4b + (inc); \
|
||||||
if(new_ls4b < (asn).ls4b) { (asn).ms1b++; } \
|
if(new_ls4b < (asn).ls4b) { (asn).ms1b++; } \
|
||||||
(asn).ls4b = new_ls4b; \
|
(asn).ls4b = new_ls4b; \
|
||||||
} while(0);
|
} while(0);
|
||||||
|
|
||||||
/* Decrement an ASN by inc (32 bits) */
|
/* 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); \
|
uint32_t new_ls4b = (asn).ls4b - (dec); \
|
||||||
if(new_ls4b > (asn).ls4b) { (asn).ms1b--; } \
|
if(new_ls4b > (asn).ls4b) { (asn).ms1b--; } \
|
||||||
(asn).ls4b = new_ls4b; \
|
(asn).ls4b = new_ls4b; \
|
||||||
} while(0);
|
} while(0);
|
||||||
|
|
||||||
/* Returns the 32-bit diff between asn1 and asn2 */
|
/* Returns the 32-bit diff between asn1 and asn2 */
|
||||||
#define ASN_DIFF(asn1, asn2) \
|
#define TSCH_ASN_DIFF(asn1, asn2) \
|
||||||
((asn1).ls4b - (asn2).ls4b)
|
((asn1).ls4b - (asn2).ls4b)
|
||||||
|
|
||||||
/* Initialize a struct asn_divisor_t */
|
/* 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).val = (val_); \
|
||||||
(div).asn_ms1b_remainder = ((0xffffffff % (val_)) + 1) % (val_); \
|
(div).asn_ms1b_remainder = ((0xffffffff % (val_)) + 1) % (val_); \
|
||||||
} while(0);
|
} while(0);
|
||||||
|
|
||||||
/* Returns the result (16 bits) of a modulo operation on ASN,
|
/* Returns the result (16 bits) of a modulo operation on ASN,
|
||||||
* with divisor being a struct asn_divisor_t */
|
* 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).ls4b % (div).val) \
|
||||||
+ (uint16_t)((asn).ms1b * (div).asn_ms1b_remainder % (div).val)) \
|
+ (uint16_t)((asn).ms1b * (div).asn_ms1b_remainder % (div).val)) \
|
||||||
% (div).val
|
% (div).val
|
||||||
|
|
|
@ -132,7 +132,7 @@ tsch_log_prepare_add(void)
|
||||||
int log_index = ringbufindex_peek_put(&log_ringbuf);
|
int log_index = ringbufindex_peek_put(&log_ringbuf);
|
||||||
if(log_index != -1) {
|
if(log_index != -1) {
|
||||||
struct tsch_log_t *log = &log_array[log_index];
|
struct tsch_log_t *log = &log_array[log_index];
|
||||||
log->asn = current_asn;
|
log->asn = tsch_current_asn;
|
||||||
log->link = current_link;
|
log->link = current_link;
|
||||||
return log;
|
return log;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -81,7 +81,7 @@ struct tsch_log_t {
|
||||||
tsch_log_rx,
|
tsch_log_rx,
|
||||||
tsch_log_message
|
tsch_log_message
|
||||||
} type;
|
} type;
|
||||||
struct asn_t asn;
|
struct tsch_asn_t asn;
|
||||||
struct tsch_link *link;
|
struct tsch_link *link;
|
||||||
union {
|
union {
|
||||||
char message[48];
|
char message[48];
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
/* Construct enhanced ACK packet and return ACK length */
|
/* Construct enhanced ACK packet and return ACK length */
|
||||||
int
|
int
|
||||||
tsch_packet_create_eack(uint8_t *buf, int buf_size,
|
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;
|
int ret;
|
||||||
uint8_t curr_len = 0;
|
uint8_t curr_len = 0;
|
||||||
|
@ -338,7 +338,7 @@ int
|
||||||
tsch_packet_update_eb(uint8_t *buf, int buf_size, uint8_t tsch_sync_ie_offset)
|
tsch_packet_update_eb(uint8_t *buf, int buf_size, uint8_t tsch_sync_ie_offset)
|
||||||
{
|
{
|
||||||
struct ieee802154_ies ies;
|
struct ieee802154_ies ies;
|
||||||
ies.ie_asn = current_asn;
|
ies.ie_asn = tsch_current_asn;
|
||||||
ies.ie_join_priority = tsch_join_priority;
|
ies.ie_join_priority = tsch_join_priority;
|
||||||
frame80215e_create_ie_tsch_synchronization(buf+tsch_sync_ie_offset, buf_size-tsch_sync_ie_offset, &ies);
|
frame80215e_create_ie_tsch_synchronization(buf+tsch_sync_ie_offset, buf_size-tsch_sync_ie_offset, &ies);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -88,7 +88,7 @@ by default, useful in case of duplicate seqno */
|
||||||
|
|
||||||
/* Construct enhanced ACK packet and return ACK length */
|
/* Construct enhanced ACK packet and return ACK length */
|
||||||
int tsch_packet_create_eack(uint8_t *buf, int buf_size,
|
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 */
|
/* Parse enhanced ACK packet, extract drift and nack */
|
||||||
int tsch_packet_parse_eack(const uint8_t *buf, int buf_size,
|
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);
|
||||||
|
|
|
@ -80,12 +80,12 @@ extern const linkaddr_t tsch_broadcast_address;
|
||||||
/* The address we use to identify EB queue */
|
/* The address we use to identify EB queue */
|
||||||
extern const linkaddr_t tsch_eb_address;
|
extern const linkaddr_t tsch_eb_address;
|
||||||
/* The current Absolute Slot Number (ASN) */
|
/* 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 uint8_t tsch_join_priority;
|
||||||
extern struct tsch_link *current_link;
|
extern struct tsch_link *current_link;
|
||||||
/* TSCH channel hopping sequence */
|
/* TSCH channel hopping sequence */
|
||||||
extern uint8_t tsch_hopping_sequence[TSCH_HOPPING_SEQUENCE_MAX_LEN];
|
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) */
|
/* TSCH timeslot timing (in rtimer ticks) */
|
||||||
extern rtimer_clock_t tsch_timing[tsch_ts_elements_count];
|
extern rtimer_clock_t tsch_timing[tsch_ts_elements_count];
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ tsch_schedule_add_slotframe(uint16_t handle, uint16_t size)
|
||||||
if(sf != NULL) {
|
if(sf != NULL) {
|
||||||
/* Initialize the slotframe */
|
/* Initialize the slotframe */
|
||||||
sf->handle = handle;
|
sf->handle = handle;
|
||||||
ASN_DIVISOR_INIT(sf->size, size);
|
TSCH_ASN_DIVISOR_INIT(sf->size, size);
|
||||||
LIST_STRUCT_INIT(sf, links_list);
|
LIST_STRUCT_INIT(sf, links_list);
|
||||||
/* Add the slotframe to the global list */
|
/* Add the slotframe to the global list */
|
||||||
list_add(slotframe_list, sf);
|
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) */
|
/* Returns the next active link after a given ASN, and a backup link (for the same ASN, with Rx flag) */
|
||||||
struct tsch_link *
|
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)
|
struct tsch_link **backup_link)
|
||||||
{
|
{
|
||||||
uint16_t time_to_curr_best = 0;
|
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 */
|
/* For each slotframe, look for the earliest occurring link */
|
||||||
while(sf != NULL) {
|
while(sf != NULL) {
|
||||||
/* Get timeslot from ASN, given the slotframe length */
|
/* 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);
|
struct tsch_link *l = list_head(sf->links_list);
|
||||||
while(l != NULL) {
|
while(l != NULL) {
|
||||||
uint16_t time_to_timeslot =
|
uint16_t time_to_timeslot =
|
||||||
|
|
|
@ -119,7 +119,7 @@ struct tsch_slotframe {
|
||||||
uint16_t handle;
|
uint16_t handle;
|
||||||
/* Number of timeslots in the slotframe.
|
/* Number of timeslots in the slotframe.
|
||||||
* Stored as struct asn_divisor_t because we often need ASN%size */
|
* 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 of links belonging to this slotframe */
|
||||||
LIST_STRUCT(links_list);
|
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);
|
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) */
|
/* 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);
|
struct tsch_link **backup_link);
|
||||||
|
|
||||||
#endif /* __TSCH_SCHEDULE_H__ */
|
#endif /* __TSCH_SCHEDULE_H__ */
|
||||||
|
|
|
@ -73,7 +73,7 @@ static aes_key keys[] = {
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
tsch_security_init_nonce(uint8_t *nonce,
|
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);
|
memcpy(nonce, sender, 8);
|
||||||
nonce[8] = asn->ms1b;
|
nonce[8] = asn->ms1b;
|
||||||
|
@ -137,7 +137,7 @@ tsch_security_mic_len(const frame802154_t *frame)
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
unsigned int
|
unsigned int
|
||||||
tsch_security_secure_frame(uint8_t *hdr, uint8_t *outbuf,
|
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;
|
frame802154_t frame;
|
||||||
uint8_t key_index = 0;
|
uint8_t key_index = 0;
|
||||||
|
@ -160,7 +160,7 @@ tsch_security_secure_frame(uint8_t *hdr, uint8_t *outbuf,
|
||||||
|
|
||||||
if(!frame.fcf.security_enabled) {
|
if(!frame.fcf.security_enabled) {
|
||||||
/* Security is not enabled for this frame, we're done */
|
/* Security is not enabled for this frame, we're done */
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read security key index */
|
/* Read security key index */
|
||||||
|
@ -200,7 +200,8 @@ tsch_security_secure_frame(uint8_t *hdr, uint8_t *outbuf,
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
unsigned int
|
unsigned int
|
||||||
tsch_security_parse_frame(const uint8_t *hdr, int hdrlen, int datalen,
|
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 generated_mic[16];
|
||||||
uint8_t key_index = 0;
|
uint8_t key_index = 0;
|
||||||
|
|
|
@ -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,
|
unsigned int tsch_security_secure_frame(uint8_t *hdr, uint8_t *outbuf,
|
||||||
int hdrlen, int datalen,
|
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
|
* \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,
|
unsigned int tsch_security_parse_frame(const uint8_t *hdr, int hdrlen,
|
||||||
int datalen, const frame802154_t *frame,
|
int datalen, const frame802154_t *frame,
|
||||||
const linkaddr_t *sender,
|
const linkaddr_t *sender,
|
||||||
struct asn_t *asn);
|
struct tsch_asn_t *asn);
|
||||||
|
|
||||||
#endif /* __TSCH_SECURITY_H__ */
|
#endif /* __TSCH_SECURITY_H__ */
|
||||||
|
|
|
@ -139,7 +139,7 @@ struct ringbufindex input_ringbuf;
|
||||||
struct input_packet input_array[TSCH_MAX_INCOMING_PACKETS];
|
struct input_packet input_array[TSCH_MAX_INCOMING_PACKETS];
|
||||||
|
|
||||||
/* Last time we received Sync-IE (ACK or data packet from a time source) */
|
/* 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 */
|
/* A global lock for manipulating data structures safely from outside of interrupt */
|
||||||
static volatile int tsch_locked = 0;
|
static volatile int tsch_locked = 0;
|
||||||
|
@ -248,9 +248,9 @@ tsch_release_lock(void)
|
||||||
|
|
||||||
/* Return channel from ASN and channel offset */
|
/* Return channel from ASN and channel offset */
|
||||||
uint8_t
|
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;
|
uint16_t index_of_offset = (index_of_0 + channel_offset) % tsch_hopping_sequence_length.val;
|
||||||
return tsch_hopping_sequence[index_of_offset];
|
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. */
|
* the original untouched. This is to allow for future retransmissions. */
|
||||||
int with_encryption = queuebuf_attr(current_packet->qb, PACKETBUF_ATTR_SECURITY_LEVEL) & 0x4;
|
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 += 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) {
|
if(with_encryption) {
|
||||||
packet = encrypted_packet;
|
packet = encrypted_packet;
|
||||||
}
|
}
|
||||||
|
@ -627,7 +627,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
|
||||||
#if LLSEC802154_ENABLED
|
#if LLSEC802154_ENABLED
|
||||||
if(ack_len != 0) {
|
if(ack_len != 0) {
|
||||||
if(!tsch_security_parse_frame(ackbuf, ack_hdrlen, ack_len - ack_hdrlen - tsch_security_mic_len(&frame),
|
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,
|
TSCH_LOG_ADD(tsch_log_message,
|
||||||
snprintf(log->message, sizeof(log->message),
|
snprintf(log->message, sizeof(log->message),
|
||||||
"!failed to authenticate ACK"));
|
"!failed to authenticate ACK"));
|
||||||
|
@ -644,7 +644,7 @@ PT_THREAD(tsch_tx_slot(struct pt *pt, struct rtimer *t))
|
||||||
if(ack_len != 0) {
|
if(ack_len != 0) {
|
||||||
if(is_time_source) {
|
if(is_time_source) {
|
||||||
int32_t eack_time_correction = US_TO_RTIMERTICKS(ack_ies.ie_time_correction);
|
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) {
|
if(eack_time_correction > SYNC_IE_BOUND) {
|
||||||
drift_correction = SYNC_IE_BOUND;
|
drift_correction = SYNC_IE_BOUND;
|
||||||
} else if(eack_time_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;
|
is_drift_correction_used = 1;
|
||||||
tsch_timesync_update(current_neighbor, since_last_timesync, drift_correction);
|
tsch_timesync_update(current_neighbor, since_last_timesync, drift_correction);
|
||||||
/* Keep track of sync time */
|
/* Keep track of sync time */
|
||||||
last_sync_asn = current_asn;
|
last_sync_asn = tsch_current_asn;
|
||||||
tsch_schedule_keepalive();
|
tsch_schedule_keepalive();
|
||||||
}
|
}
|
||||||
mac_tx_status = MAC_TX_OK;
|
mac_tx_status = MAC_TX_OK;
|
||||||
|
@ -793,7 +793,7 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t))
|
||||||
/* Read packet */
|
/* Read packet */
|
||||||
current_input->len = NETSTACK_RADIO.read((void *)current_input->payload, TSCH_PACKET_MAX_LEN);
|
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);
|
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->rssi = (signed)radio_last_rssi;
|
||||||
current_input->channel = current_channel;
|
current_input->channel = current_channel;
|
||||||
header_len = frame802154_parse((uint8_t *)current_input->payload, current_input->len, &frame);
|
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(frame_valid) {
|
||||||
if(tsch_security_parse_frame(
|
if(tsch_security_parse_frame(
|
||||||
current_input->payload, header_len, current_input->len - header_len - tsch_security_mic_len(&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);
|
current_input->len -= tsch_security_mic_len(&frame);
|
||||||
} else {
|
} else {
|
||||||
TSCH_LOG_ADD(tsch_log_message,
|
TSCH_LOG_ADD(tsch_log_message,
|
||||||
|
@ -861,10 +861,11 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t))
|
||||||
ack_len = tsch_packet_create_eack(ack_buf, sizeof(ack_buf),
|
ack_len = tsch_packet_create_eack(ack_buf, sizeof(ack_buf),
|
||||||
&source_address, frame.seq, (int16_t)RTIMERTICKS_TO_US(estimated_drift), do_nack);
|
&source_address, frame.seq, (int16_t)RTIMERTICKS_TO_US(estimated_drift), do_nack);
|
||||||
|
|
||||||
|
if(ack_len > 0) {
|
||||||
#if LLSEC802154_ENABLED
|
#if LLSEC802154_ENABLED
|
||||||
if(tsch_is_pan_secured) {
|
if(tsch_is_pan_secured) {
|
||||||
/* Secure ACK frame. There is only header and header IEs, therefore data len == 0. */
|
/* 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 */
|
#endif /* LLSEC802154_ENABLED */
|
||||||
|
|
||||||
|
@ -878,13 +879,14 @@ PT_THREAD(tsch_rx_slot(struct pt *pt, struct rtimer *t))
|
||||||
NETSTACK_RADIO.transmit(ack_len);
|
NETSTACK_RADIO.transmit(ack_len);
|
||||||
tsch_radio_off(TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT);
|
tsch_radio_off(TSCH_RADIO_CMD_OFF_WITHIN_TIMESLOT);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If the sender is a time source, proceed to clock drift compensation */
|
/* If the sender is a time source, proceed to clock drift compensation */
|
||||||
n = tsch_queue_get_nbr(&source_address);
|
n = tsch_queue_get_nbr(&source_address);
|
||||||
if(n != NULL && n->is_time_source) {
|
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 */
|
/* Keep track of last sync time */
|
||||||
last_sync_asn = current_asn;
|
last_sync_asn = tsch_current_asn;
|
||||||
/* Save estimated drift */
|
/* Save estimated drift */
|
||||||
drift_correction = -estimated_drift;
|
drift_correction = -estimated_drift;
|
||||||
is_drift_correction_used = 1;
|
is_drift_correction_used = 1;
|
||||||
|
@ -970,7 +972,7 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr))
|
||||||
is_active_slot = current_packet != NULL || (current_link->link_options & LINK_OPTION_RX);
|
is_active_slot = current_packet != NULL || (current_link->link_options & LINK_OPTION_RX);
|
||||||
if(is_active_slot) {
|
if(is_active_slot) {
|
||||||
/* Hop channel */
|
/* 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);
|
NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, current_channel);
|
||||||
/* Turn the radio on already here if configured so; necessary for radios with slow startup */
|
/* 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);
|
tsch_radio_on(TSCH_RADIO_CMD_ON_START_OF_TIMESLOT);
|
||||||
|
@ -996,12 +998,12 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr))
|
||||||
/* End of slot operation, schedule next slot or resynchronize */
|
/* End of slot operation, schedule next slot or resynchronize */
|
||||||
|
|
||||||
/* Do we need to resynchronize? i.e., wait for EB again */
|
/* 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])))) {
|
(100 * TSCH_CLOCK_TO_SLOTS(TSCH_DESYNC_THRESHOLD / 100, tsch_timing[tsch_ts_timeslot_length])))) {
|
||||||
TSCH_LOG_ADD(tsch_log_message,
|
TSCH_LOG_ADD(tsch_log_message,
|
||||||
snprintf(log->message, sizeof(log->message),
|
snprintf(log->message, sizeof(log->message),
|
||||||
"! leaving the network, last sync %u",
|
"! 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;
|
last_timesource_neighbor = NULL;
|
||||||
tsch_disassociate();
|
tsch_disassociate();
|
||||||
|
@ -1023,14 +1025,14 @@ PT_THREAD(tsch_slot_operation(struct rtimer *t, void *ptr))
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get next active link */
|
/* 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) {
|
if(current_link == NULL) {
|
||||||
/* There is no next link. Fall back to default
|
/* There is no next link. Fall back to default
|
||||||
* behavior: wake up at the next slot. */
|
* behavior: wake up at the next slot. */
|
||||||
timeslot_diff = 1;
|
timeslot_diff = 1;
|
||||||
}
|
}
|
||||||
/* Update ASN */
|
/* Update ASN */
|
||||||
ASN_INC(current_asn, timeslot_diff);
|
TSCH_ASN_INC(tsch_current_asn, timeslot_diff);
|
||||||
/* Time to next wake up */
|
/* Time to next wake up */
|
||||||
time_to_next_active_slot = timeslot_diff * tsch_timing[tsch_ts_timeslot_length] + drift_correction;
|
time_to_next_active_slot = timeslot_diff * tsch_timing[tsch_ts_timeslot_length] + drift_correction;
|
||||||
drift_correction = 0;
|
drift_correction = 0;
|
||||||
|
@ -1061,14 +1063,14 @@ tsch_slot_operation_start(void)
|
||||||
do {
|
do {
|
||||||
uint16_t timeslot_diff;
|
uint16_t timeslot_diff;
|
||||||
/* Get next active link */
|
/* 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) {
|
if(current_link == NULL) {
|
||||||
/* There is no next link. Fall back to default
|
/* There is no next link. Fall back to default
|
||||||
* behavior: wake up at the next slot. */
|
* behavior: wake up at the next slot. */
|
||||||
timeslot_diff = 1;
|
timeslot_diff = 1;
|
||||||
}
|
}
|
||||||
/* Update ASN */
|
/* Update ASN */
|
||||||
ASN_INC(current_asn, timeslot_diff);
|
TSCH_ASN_INC(tsch_current_asn, timeslot_diff);
|
||||||
/* Time to next wake up */
|
/* Time to next wake up */
|
||||||
time_to_next_active_slot = timeslot_diff * tsch_timing[tsch_ts_timeslot_length];
|
time_to_next_active_slot = timeslot_diff * tsch_timing[tsch_ts_timeslot_length];
|
||||||
/* Update current slot start */
|
/* Update current slot start */
|
||||||
|
@ -1080,11 +1082,11 @@ tsch_slot_operation_start(void)
|
||||||
/* Start actual slot operation */
|
/* Start actual slot operation */
|
||||||
void
|
void
|
||||||
tsch_slot_operation_sync(rtimer_clock_t next_slot_start,
|
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_slot_start = next_slot_start;
|
||||||
current_asn = *next_slot_asn;
|
tsch_current_asn = *next_slot_asn;
|
||||||
last_sync_asn = current_asn;
|
last_sync_asn = tsch_current_asn;
|
||||||
current_link = NULL;
|
current_link = NULL;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -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 */
|
/* Stores data about an incoming packet */
|
||||||
struct input_packet {
|
struct input_packet {
|
||||||
uint8_t payload[TSCH_PACKET_MAX_LEN]; /* Packet payload */
|
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 */
|
int len; /* Packet len */
|
||||||
int16_t rssi; /* RSSI for this packet */
|
int16_t rssi; /* RSSI for this packet */
|
||||||
uint8_t channel; /* Channel we received the packet on */
|
uint8_t channel; /* Channel we received the packet on */
|
||||||
|
@ -107,7 +107,7 @@ extern struct input_packet input_array[TSCH_MAX_INCOMING_PACKETS];
|
||||||
/********** Functions *********/
|
/********** Functions *********/
|
||||||
|
|
||||||
/* Returns a 802.15.4 channel from an ASN and channel offset */
|
/* 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? */
|
/* Is TSCH locked? */
|
||||||
int tsch_is_locked(void);
|
int tsch_is_locked(void);
|
||||||
/* Lock TSCH (no link operation) */
|
/* Lock TSCH (no link operation) */
|
||||||
|
@ -117,7 +117,7 @@ void tsch_release_lock(void);
|
||||||
/* Set global time before starting slot operation,
|
/* Set global time before starting slot operation,
|
||||||
* with a rtimer time and an ASN */
|
* with a rtimer time and an ASN */
|
||||||
void tsch_slot_operation_sync(rtimer_clock_t next_slot_start,
|
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 */
|
/* Start actual slot operation */
|
||||||
void tsch_slot_operation_start(void);
|
void tsch_slot_operation_start(void);
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ NBR_TABLE(struct eb_stat, eb_stats);
|
||||||
|
|
||||||
/* TSCH channel hopping sequence */
|
/* TSCH channel hopping sequence */
|
||||||
uint8_t tsch_hopping_sequence[TSCH_HOPPING_SEQUENCE_MAX_LEN];
|
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) */
|
/* Default TSCH timeslot timing (in micro-second) */
|
||||||
static const uint16_t tsch_default_timing_us[tsch_ts_elements_count] = {
|
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? */
|
/* Is the PAN running link-layer security? */
|
||||||
int tsch_is_pan_secured = LLSEC802154_ENABLED;
|
int tsch_is_pan_secured = LLSEC802154_ENABLED;
|
||||||
/* The current Absolute Slot Number (ASN) */
|
/* The current Absolute Slot Number (ASN) */
|
||||||
struct asn_t current_asn;
|
struct tsch_asn_t tsch_current_asn;
|
||||||
/* Device rank or join priority:
|
/* Device rank or join priority:
|
||||||
* For PAN coordinator: 0 -- lower is better */
|
* For PAN coordinator: 0 -- lower is better */
|
||||||
uint8_t tsch_join_priority;
|
uint8_t tsch_join_priority;
|
||||||
|
@ -202,7 +202,7 @@ tsch_reset(void)
|
||||||
tsch_queue_update_time_source(NULL);
|
tsch_queue_update_time_source(NULL);
|
||||||
/* Initialize global variables */
|
/* Initialize global variables */
|
||||||
tsch_join_priority = 0xff;
|
tsch_join_priority = 0xff;
|
||||||
ASN_INIT(current_asn, 0, 0);
|
TSCH_ASN_INIT(tsch_current_asn, 0, 0);
|
||||||
current_link = NULL;
|
current_link = NULL;
|
||||||
/* Reset timeslot timing to defaults */
|
/* Reset timeslot timing to defaults */
|
||||||
for(i = 0; i < tsch_ts_elements_count; i++) {
|
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? */
|
/* Did the EB come from our time source? */
|
||||||
if(n != NULL && linkaddr_cmp((linkaddr_t *)&frame.src_addr, &n->addr)) {
|
if(n != NULL && linkaddr_cmp((linkaddr_t *)&frame.src_addr, &n->addr)) {
|
||||||
/* Check for ASN drift */
|
/* 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) {
|
if(asn_diff != 0) {
|
||||||
/* We disagree with our time source's ASN -- leave the network */
|
/* We disagree with our time source's ASN -- leave the network */
|
||||||
PRINTF("TSCH:! ASN drifted by %ld, leaving the network\n", asn_diff);
|
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);
|
frame802154_set_pan_id(IEEE802154_PANID);
|
||||||
/* Initialize hopping sequence as default */
|
/* Initialize hopping sequence as default */
|
||||||
memcpy(tsch_hopping_sequence, TSCH_DEFAULT_HOPPING_SEQUENCE, sizeof(TSCH_DEFAULT_HOPPING_SEQUENCE));
|
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
|
#if TSCH_SCHEDULE_WITH_6TISCH_MINIMAL
|
||||||
tsch_schedule_create_minimal();
|
tsch_schedule_create_minimal();
|
||||||
#endif
|
#endif
|
||||||
|
@ -410,10 +410,10 @@ tsch_start_coordinator(void)
|
||||||
tsch_join_priority = 0;
|
tsch_join_priority = 0;
|
||||||
|
|
||||||
PRINTF("TSCH: starting as coordinator, PAN ID %x, asn-%x.%lx\n",
|
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 */
|
/* Start slot operation */
|
||||||
tsch_slot_operation_sync(RTIMER_NOW(), ¤t_asn);
|
tsch_slot_operation_sync(RTIMER_NOW(), &tsch_current_asn);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Leave the TSCH network */
|
/* Leave the TSCH network */
|
||||||
|
@ -442,7 +442,7 @@ tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_asn = ies.ie_asn;
|
tsch_current_asn = ies.ie_asn;
|
||||||
tsch_join_priority = ies.ie_join_priority + 1;
|
tsch_join_priority = ies.ie_join_priority + 1;
|
||||||
|
|
||||||
#if TSCH_JOIN_SECURED_ONLY
|
#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 LLSEC802154_ENABLED
|
||||||
if(!tsch_security_parse_frame(input_eb->payload, hdrlen,
|
if(!tsch_security_parse_frame(input_eb->payload, hdrlen,
|
||||||
input_eb->len - hdrlen - tsch_security_mic_len(&frame),
|
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");
|
PRINTF("TSCH:! parse_eb: failed to authenticate\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -494,11 +494,11 @@ tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp)
|
||||||
/* TSCH hopping sequence */
|
/* TSCH hopping sequence */
|
||||||
if(ies.ie_channel_hopping_sequence_id == 0) {
|
if(ies.ie_channel_hopping_sequence_id == 0) {
|
||||||
memcpy(tsch_hopping_sequence, TSCH_DEFAULT_HOPPING_SEQUENCE, sizeof(TSCH_DEFAULT_HOPPING_SEQUENCE));
|
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 {
|
} else {
|
||||||
if(ies.ie_hopping_sequence_len <= sizeof(tsch_hopping_sequence)) {
|
if(ies.ie_hopping_sequence_len <= sizeof(tsch_hopping_sequence)) {
|
||||||
memcpy(tsch_hopping_sequence, ies.ie_hopping_sequence_list, ies.ie_hopping_sequence_len);
|
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 {
|
} else {
|
||||||
PRINTF("TSCH:! parse_eb: hopping sequence too long (%u)\n", ies.ie_hopping_sequence_len);
|
PRINTF("TSCH:! parse_eb: hopping sequence too long (%u)\n", ies.ie_hopping_sequence_len);
|
||||||
return 0;
|
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 */
|
/* 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*/
|
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_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) {
|
if(asn_diff > asn_threshold) {
|
||||||
PRINTF("TSCH:! EB ASN rejected %lx %lx %ld\n",
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -562,7 +562,7 @@ tsch_associate(const struct input_packet *input_eb, rtimer_clock_t timestamp)
|
||||||
frame802154_set_pan_id(frame.src_pid);
|
frame802154_set_pan_id(frame.src_pid);
|
||||||
|
|
||||||
/* Synchronize on EB */
|
/* 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 */
|
/* Update global flags */
|
||||||
tsch_is_associated = 1;
|
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 ",
|
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,
|
tsch_is_pan_secured,
|
||||||
frame.src_pid,
|
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_tsch_timeslot_id,
|
||||||
ies.ie_channel_hopping_sequence_id,
|
ies.ie_channel_hopping_sequence_id,
|
||||||
ies.ie_tsch_slotframe_and_link.slotframe_size,
|
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 */
|
/* Time when we started scanning on current_channel */
|
||||||
static clock_time_t current_channel_since;
|
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);
|
etimer_set(&scan_timer, CLOCK_SECOND / TSCH_ASSOCIATION_POLL_FREQUENCY);
|
||||||
current_channel_since = clock_time();
|
current_channel_since = clock_time();
|
||||||
|
@ -749,7 +749,7 @@ PROCESS_THREAD(tsch_send_eb_process, ev, data)
|
||||||
#endif /* LLSEC802154_ENABLED */
|
#endif /* LLSEC802154_ENABLED */
|
||||||
eb_len = tsch_packet_create_eb(packetbuf_dataptr(), PACKETBUF_SIZE,
|
eb_len = tsch_packet_create_eb(packetbuf_dataptr(), PACKETBUF_SIZE,
|
||||||
&hdr_len, &tsch_sync_ie_offset);
|
&hdr_len, &tsch_sync_ie_offset);
|
||||||
if(eb_len != 0) {
|
if(eb_len > 0) {
|
||||||
struct tsch_packet *p;
|
struct tsch_packet *p;
|
||||||
packetbuf_set_datalen(eb_len);
|
packetbuf_set_datalen(eb_len);
|
||||||
/* Enqueue EB packet */
|
/* Enqueue EB packet */
|
||||||
|
|
|
@ -201,7 +201,7 @@ PROCESS_THREAD(node_process, ev, data)
|
||||||
if (host_found) {
|
if (host_found) {
|
||||||
/* Make sample count dependent on asn. After a disconnect, waveforms remain
|
/* Make sample count dependent on asn. After a disconnect, waveforms remain
|
||||||
synchronous. Use node_mac to create phase offset between waveforms in different nodes */
|
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]);
|
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]);
|
my_sprintf(udp_buf, waveform_table[selected_waveform].table[sample_count]);
|
||||||
uip_udp_packet_send(udp_conn_tx, udp_buf, strlen(udp_buf));
|
uip_udp_packet_send(udp_conn_tx, udp_buf, strlen(udp_buf));
|
||||||
|
|
203
regression-tests/25-ieee802154/02-tsch-packet-create.csc
Normal file
203
regression-tests/25-ieee802154/02-tsch-packet-create.csc
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<simconf>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/mrm</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/avrora</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/collect-view</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
|
||||||
|
<project EXPORT="discard">[APPS_DIR]/radiologger-headless</project>
|
||||||
|
<simulation>
|
||||||
|
<title>My simulation</title>
|
||||||
|
<randomseed>123456</randomseed>
|
||||||
|
<motedelay_us>1000000</motedelay_us>
|
||||||
|
<radiomedium>
|
||||||
|
org.contikios.cooja.radiomediums.UDGM
|
||||||
|
<transmitting_range>0.0</transmitting_range>
|
||||||
|
<interference_range>0.0</interference_range>
|
||||||
|
<success_ratio_tx>1.0</success_ratio_tx>
|
||||||
|
<success_ratio_rx>1.0</success_ratio_rx>
|
||||||
|
</radiomedium>
|
||||||
|
<events>
|
||||||
|
<logoutput>40000</logoutput>
|
||||||
|
</events>
|
||||||
|
<motetype>
|
||||||
|
org.contikios.cooja.contikimote.ContikiMoteType
|
||||||
|
<identifier>mtype713</identifier>
|
||||||
|
<description>default</description>
|
||||||
|
<source>[CONTIKI_DIR]/regression-tests/25-ieee802154/code/test-tsch-packet.c</source>
|
||||||
|
<commands>make TARGET=cooja clean
|
||||||
|
make TEST_CONFIG_TYPE=DEFAULT test-tsch-packet.cooja TARGET=cooja</commands>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiEEPROM</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||||
|
<symbols>false</symbols>
|
||||||
|
</motetype>
|
||||||
|
<motetype>
|
||||||
|
org.contikios.cooja.contikimote.ContikiMoteType
|
||||||
|
<identifier>mtype740</identifier>
|
||||||
|
<description>security on</description>
|
||||||
|
<source>[CONTIKI_DIR]/regression-tests/25-ieee802154/code/test-tsch-packet.c</source>
|
||||||
|
<commands>make TARGET=cooja clean
|
||||||
|
make TEST_CONFIG_TYPE=SECURITY_ON test-tsch-packet.cooja TARGET=cooja</commands>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiEEPROM</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||||
|
<symbols>false</symbols>
|
||||||
|
</motetype>
|
||||||
|
<motetype>
|
||||||
|
org.contikios.cooja.contikimote.ContikiMoteType
|
||||||
|
<identifier>mtype399</identifier>
|
||||||
|
<description>all enabled</description>
|
||||||
|
<source>[CONTIKI_DIR]/regression-tests/25-ieee802154/code/test-tsch-packet.c</source>
|
||||||
|
<commands>make TARGET=cooja clean
|
||||||
|
make TEST_CONFIG_TYPE=ALL_ENABLED test-tsch-packet.cooja TARGET=cooja</commands>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiEEPROM</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
|
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||||
|
<symbols>false</symbols>
|
||||||
|
</motetype>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>-49.23869609407765</x>
|
||||||
|
<y>-36.33693008116223</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>1</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
|
||||||
|
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype713</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>-17.772442808950224</x>
|
||||||
|
<y>-36.862574776701464</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>2</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
|
||||||
|
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype740</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
<mote>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.interfaces.Position
|
||||||
|
<x>14.488632230762605</x>
|
||||||
|
<y>-35.15143001217301</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||||
|
<id>3</id>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||||
|
<bitrate>250.0</bitrate>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
|
||||||
|
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>mtype399</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
</simulation>
|
||||||
|
<plugin>
|
||||||
|
org.contikios.cooja.plugins.SimControl
|
||||||
|
<width>280</width>
|
||||||
|
<z>2</z>
|
||||||
|
<height>160</height>
|
||||||
|
<location_x>400</location_x>
|
||||||
|
<location_y>0</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
org.contikios.cooja.plugins.Visualizer
|
||||||
|
<plugin_config>
|
||||||
|
<moterelations>true</moterelations>
|
||||||
|
<skin>org.contikios.cooja.plugins.skins.IDVisualizerSkin</skin>
|
||||||
|
<skin>org.contikios.cooja.plugins.skins.GridVisualizerSkin</skin>
|
||||||
|
<skin>org.contikios.cooja.plugins.skins.UDGMVisualizerSkin</skin>
|
||||||
|
<skin>org.contikios.cooja.plugins.skins.AttributeVisualizerSkin</skin>
|
||||||
|
<viewport>3.714690054486387 0.0 0.0 3.714690054486387 248.5428583129116 318.25485368648356</viewport>
|
||||||
|
</plugin_config>
|
||||||
|
<width>400</width>
|
||||||
|
<z>0</z>
|
||||||
|
<height>400</height>
|
||||||
|
<location_x>1</location_x>
|
||||||
|
<location_y>1</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
org.contikios.cooja.plugins.ScriptRunner
|
||||||
|
<plugin_config>
|
||||||
|
<scriptfile>[CONTIKI_DIR]/regression-tests/25-ieee802154/js/02-tsch-packet-create.js</scriptfile>
|
||||||
|
<active>true</active>
|
||||||
|
</plugin_config>
|
||||||
|
<width>495</width>
|
||||||
|
<z>1</z>
|
||||||
|
<height>525</height>
|
||||||
|
<location_x>185</location_x>
|
||||||
|
<location_y>162</location_y>
|
||||||
|
</plugin>
|
||||||
|
</simconf>
|
||||||
|
|
|
@ -1,8 +1,22 @@
|
||||||
all: test-panid-handling
|
all: test-panid-handling test-tcsh-create-packet
|
||||||
|
|
||||||
APPS += unit-test
|
APPS += unit-test
|
||||||
|
MODULES += core/net/mac/tsch
|
||||||
CFLAGS += -D PROJECT_CONF_H=\"project-conf.h\"
|
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 = ../../..
|
||||||
CONTIKI_WITH_IPV6 = 1
|
CONTIKI_WITH_IPV6 = 1
|
||||||
include $(CONTIKI)/Makefile.include
|
include $(CONTIKI)/Makefile.include
|
||||||
|
|
|
@ -29,4 +29,13 @@
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef _PROJECT_CONF_H_
|
||||||
|
#define _PROJECT_CONF_H_
|
||||||
|
|
||||||
#define UNIT_TEST_PRINT_FUNCTION test_print_report
|
#define UNIT_TEST_PRINT_FUNCTION test_print_report
|
||||||
|
|
||||||
|
#if WITH_TSCH
|
||||||
|
#include "project-tsch-conf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !_PROJECT_CONF_H_ */
|
||||||
|
|
73
regression-tests/25-ieee802154/code/project-tsch-conf.h
Normal file
73
regression-tests/25-ieee802154/code/project-tsch-conf.h
Normal file
|
@ -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 */
|
386
regression-tests/25-ieee802154/code/test-tsch-packet.c
Normal file
386
regression-tests/25-ieee802154/code/test-tsch-packet.c
Normal file
|
@ -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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
#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();
|
||||||
|
}
|
27
regression-tests/25-ieee802154/js/02-tsch-packet-create.js
Normal file
27
regression-tests/25-ieee802154/js/02-tsch-packet-create.js
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue