43 #include "net/mac/tsch/tsch.h"
44 #include "net/mac/tsch/tsch-packet.h"
46 #include "net/mac/tsch/tsch-schedule.h"
47 #include "net/mac/tsch/tsch-security.h"
48 #include "net/mac/tsch/tsch-log.h"
58 #if TSCH_LOG_LEVEL >= 1
59 #define DEBUG DEBUG_PRINT
61 #define DEBUG DEBUG_NONE
68 tsch_packet_create_eack(uint8_t *buf,
int buf_size,
69 linkaddr_t *dest_addr, uint8_t seqno, int16_t drift,
int nack)
74 struct ieee802154_ies ies;
76 memset(&p, 0,
sizeof(p));
86 #if TSCH_PACKET_EACK_WITH_DEST_ADDR
87 if(dest_addr !=
NULL) {
92 #if TSCH_PACKET_EACK_WITH_SRC_ADDR
97 #if LLSEC802154_ENABLED
98 if(tsch_is_pan_secured) {
113 memset(&ies, 0,
sizeof(ies));
114 ies.ie_time_correction = drift;
115 ies.ie_is_nack = nack;
127 tsch_packet_parse_eack(
const uint8_t *buf,
int buf_size,
128 uint8_t seqno,
frame802154_t *frame,
struct ieee802154_ies *ies, uint8_t *hdr_len)
130 uint8_t curr_len = 0;
134 if(frame ==
NULL || buf_size < 0) {
141 if(hdr_len !=
NULL) {
147 if(seqno != frame->
seq) {
152 if(frame802154_check_dest_panid(frame) == 0) {
157 if(frame802154_extract_linkaddr(frame,
NULL, &dest) == 0 ||
164 memset(ies, 0,
sizeof(
struct ieee802154_ies));
169 #if LLSEC802154_ENABLED
171 mic_len = tsch_security_mic_len(frame);
172 if(buf_size < curr_len + mic_len) {
177 if((ret = frame802154e_parse_information_elements(buf + curr_len, buf_size - curr_len - mic_len, ies)) == -1) {
183 if(hdr_len !=
NULL) {
184 *hdr_len += ies->ie_payload_ie_offset;
192 tsch_packet_create_eb(uint8_t *buf,
int buf_size, uint8_t seqno,
193 uint8_t *hdr_len, uint8_t *tsch_sync_ie_offset)
196 uint8_t curr_len = 0;
197 uint8_t mlme_ie_offset;
200 struct ieee802154_ies ies;
202 if(buf_size < TSCH_PACKET_MAX_LEN) {
207 memset(&p, 0,
sizeof(p));
219 p.
src_pid = frame802154_get_pan_id();
220 p.
dest_pid = frame802154_get_pan_id();
225 #if LLSEC802154_ENABLED
226 if(tsch_is_pan_secured) {
241 memset(&ies, 0,
sizeof(ies));
244 #if TSCH_PACKET_EB_WITH_TIMESLOT_TIMING
247 ies.ie_tsch_timeslot_id = 1;
248 for(i = 0; i < tsch_ts_elements_count; i++) {
249 ies.ie_tsch_timeslot[i] = RTIMERTICKS_TO_US(tsch_timing[i]);
255 #if TSCH_PACKET_EB_WITH_HOPPING_SEQUENCE
256 if(tsch_hopping_sequence_length.val <=
sizeof(ies.ie_hopping_sequence_list)) {
257 ies.ie_channel_hopping_sequence_id = 1;
258 ies.ie_hopping_sequence_len = tsch_hopping_sequence_length.val;
259 memcpy(ies.ie_hopping_sequence_list, tsch_hopping_sequence, ies.ie_hopping_sequence_len);
264 #if TSCH_PACKET_EB_WITH_SLOTFRAME_AND_LINK
267 struct tsch_slotframe *sf0 = tsch_schedule_get_slotframe_by_handle(0);
268 struct tsch_link *link0 = tsch_schedule_get_link_by_timeslot(sf0, 0);
270 ies.ie_tsch_slotframe_and_link.num_slotframes = 1;
271 ies.ie_tsch_slotframe_and_link.slotframe_handle = sf0->handle;
272 ies.ie_tsch_slotframe_and_link.slotframe_size = sf0->size.val;
273 ies.ie_tsch_slotframe_and_link.num_links = 1;
274 ies.ie_tsch_slotframe_and_link.links[0].timeslot = link0->timeslot;
275 ies.ie_tsch_slotframe_and_link.links[0].channel_offset = link0->channel_offset;
276 ies.ie_tsch_slotframe_and_link.links[0].link_options = link0->link_options;
282 if((ret = frame80215e_create_ie_header_list_termination_1(buf + curr_len, buf_size - curr_len, &ies)) == -1) {
288 if(hdr_len !=
NULL) {
294 mlme_ie_offset = curr_len;
298 if(tsch_sync_ie_offset !=
NULL) {
299 *tsch_sync_ie_offset = curr_len;
301 if((ret = frame80215e_create_ie_tsch_synchronization(buf + curr_len, buf_size - curr_len, &ies)) == -1) {
306 if((ret = frame80215e_create_ie_tsch_timeslot(buf + curr_len, buf_size - curr_len, &ies)) == -1) {
311 if((ret = frame80215e_create_ie_tsch_channel_hopping_sequence(buf + curr_len, buf_size - curr_len, &ies)) == -1) {
316 if((ret = frame80215e_create_ie_tsch_slotframe_and_link(buf + curr_len, buf_size - curr_len, &ies)) == -1) {
321 ies.ie_mlme_len = curr_len - mlme_ie_offset - 2;
322 if((ret = frame80215e_create_ie_mlme(buf + mlme_ie_offset, buf_size - mlme_ie_offset, &ies)) == -1) {
339 tsch_packet_update_eb(uint8_t *buf,
int buf_size, uint8_t tsch_sync_ie_offset)
341 struct ieee802154_ies ies;
342 ies.ie_asn = current_asn;
343 ies.ie_join_priority = tsch_join_priority;
344 frame80215e_create_ie_tsch_synchronization(buf+tsch_sync_ie_offset, buf_size-tsch_sync_ie_offset, &ies);
350 tsch_packet_parse_eb(
const uint8_t *buf,
int buf_size,
351 frame802154_t *frame,
struct ieee802154_ies *ies, uint8_t *hdr_len,
int frame_without_mic)
353 uint8_t curr_len = 0;
356 if(frame ==
NULL || buf_size < 0) {
362 PRINTF(
"TSCH:! parse_eb: failed to parse frame\n");
368 PRINTF(
"TSCH:! parse_eb: frame is not a valid TSCH beacon. Frame version %u, type %u, FCF %02x %02x\n",
370 PRINTF(
"TSCH:! parse_eb: frame was from 0x%x/", frame->
src_pid);
372 PRINTF(
" to 0x%x/", frame->
dest_pid);
378 if(hdr_len !=
NULL) {
384 memset(ies, 0,
sizeof(
struct ieee802154_ies));
385 ies->ie_join_priority = 0xff;
390 #if LLSEC802154_ENABLED
391 if(!frame_without_mic) {
392 mic_len = tsch_security_mic_len(frame);
393 if(buf_size < curr_len + mic_len) {
400 if((ret = frame802154e_parse_information_elements(buf + curr_len, buf_size - curr_len - mic_len, ies)) == -1) {
401 PRINTF(
"TSCH:! parse_eb: failed to parse IEs\n");
407 if(hdr_len !=
NULL) {
408 *hdr_len += ies->ie_payload_ie_offset;
uint8_t security_enabled
1 bit.
uint16_t src_pid
Source PAN ID.
frame802154_scf_t security_control
Security control bitfield.
uint8_t dest_addr[8]
Destination address.
uint8_t key_id_mode
2 bit.
uint16_t dest_pid
Destination PAN ID.
uint8_t key_index
Key Index subfield.
frame802154_fcf_t fcf
Frame control field.
uint8_t ie_list_present
1 bit.
uint8_t src_addr[8]
Source address.
uint8_t seq
Sequence number.
Private TSCH definitions (meant for use by TSCH implementation files only) ...
const linkaddr_t linkaddr_null
The null Rime address.
Header file for the Rime buffer (packetbuf) management
int frame802154_create(frame802154_t *p, uint8_t *buf)
Creates a frame for transmission over the air.
Interface to anti-replay mechanisms.
int frame80215e_create_ie_header_ack_nack_time_correction(uint8_t *buf, int len, struct ieee802154_ies *ies)
Insert various Information Elements.
A set of debugging macros for the netstack
#define NULL
The null pointer.
802.15.4 frame creation and parsing functions
int frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
Parses an input frame.
uint8_t security_level
3 bit.
uint8_t src_addr_mode
2 bit.
uint8_t frame_counter_size
1 bit.
frame802154_aux_hdr_t aux_hdr
Aux security header.
uint8_t dest_addr_mode
2 bit.
uint8_t panid_compression
1 bit.
int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two Rime addresses.
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a Rime address.
linkaddr_t linkaddr_node_addr
The Rime address of the node.
uint8_t frame_version
2 bit.
Parameters used by the frame802154_create() function.
uint8_t frame_counter_suppression
1 bit.
Include file for the Contiki low-layer network stack (NETSTACK)
A MAC framer for IEEE 802.15.4
uint8_t sequence_number_suppression
< 1 bit.