57 #define LOG_MODULE "TSCH Pkt" 58 #define LOG_LEVEL LOG_LEVEL_MAC 71 static struct packetbuf_attr eackbuf_attrs[PACKETBUF_NUM_ATTRS];
74 #define IEEE802154_FRAME_PENDING_BIT_OFFSET 4 78 tsch_packet_eackbuf_set_attr(uint8_t type,
const packetbuf_attr_t val)
80 eackbuf_attrs[type].val = val;
86 tsch_packet_eackbuf_attr(uint8_t type)
88 return eackbuf_attrs[type].val;
94 const linkaddr_t *dest_addr, uint8_t seqno,
95 int16_t drift,
int nack)
98 struct ieee802154_ies ies;
106 memset(eackbuf_attrs, 0,
sizeof(eackbuf_attrs));
108 tsch_packet_eackbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_ACKFRAME);
109 tsch_packet_eackbuf_set_attr(PACKETBUF_ATTR_MAC_METADATA, 1);
110 tsch_packet_eackbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, seqno);
112 tsch_packet_eackbuf_set_attr(PACKETBUF_ATTR_MAC_NO_DEST_ADDR, 1);
113 #if TSCH_PACKET_EACK_WITH_DEST_ADDR 114 if(dest_addr != NULL) {
115 tsch_packet_eackbuf_set_attr(PACKETBUF_ATTR_MAC_NO_DEST_ADDR, 0);
120 tsch_packet_eackbuf_set_attr(PACKETBUF_ATTR_MAC_NO_SRC_ADDR, 1);
121 #if TSCH_PACKET_EACK_WITH_SRC_ADDR 122 tsch_packet_eackbuf_set_attr(PACKETBUF_ATTR_MAC_NO_SRC_ADDR, 0);
126 #if LLSEC802154_ENABLED 127 if(tsch_is_pan_secured) {
128 tsch_packet_eackbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL,
129 TSCH_SECURITY_KEY_SEC_LEVEL_ACK);
130 tsch_packet_eackbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE,
131 FRAME802154_1_BYTE_KEY_ID_MODE);
132 tsch_packet_eackbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX,
133 TSCH_SECURITY_KEY_INDEX_ACK);
137 framer_802154_setup_params(tsch_packet_eackbuf_attr, 0, ¶ms);
140 memset(buf, 0, buf_len);
143 memset(&ies, 0,
sizeof(ies));
144 ies.ie_time_correction = drift;
145 ies.ie_is_nack = nack;
149 buf_len - hdr_len, &ies);
163 uint8_t seqno,
frame802154_t *frame,
struct ieee802154_ies *ies, uint8_t *hdr_len)
165 uint8_t curr_len = 0;
169 if(frame == NULL || buf_size < 0) {
176 if(hdr_len != NULL) {
182 if(seqno != frame->
seq) {
187 if(frame802154_check_dest_panid(frame) == 0) {
192 if(frame802154_extract_linkaddr(frame, NULL, &dest) == 0 ||
199 memset(ies, 0,
sizeof(
struct ieee802154_ies));
204 #if LLSEC802154_ENABLED 207 if(buf_size < curr_len + mic_len) {
212 if((ret = frame802154e_parse_information_elements(buf + curr_len, buf_size - curr_len - mic_len, ies)) == -1) {
218 if(hdr_len != NULL) {
219 *hdr_len += ies->ie_payload_ie_offset;
229 struct ieee802154_ies ies;
232 const uint16_t payload_ie_hdr_len = 2;
237 memset(&ies, 0,
sizeof(ies));
240 #if TSCH_PACKET_EB_WITH_TIMESLOT_TIMING 243 ies.ie_tsch_timeslot_id = 1;
244 for(i = 0; i < tsch_ts_elements_count; i++) {
245 ies.ie_tsch_timeslot[i] = RTIMERTICKS_TO_US(tsch_timing[i]);
251 #if TSCH_PACKET_EB_WITH_HOPPING_SEQUENCE 252 if(tsch_hopping_sequence_length.val <=
sizeof(ies.ie_hopping_sequence_list)) {
253 ies.ie_channel_hopping_sequence_id = 1;
254 ies.ie_hopping_sequence_len = tsch_hopping_sequence_length.val;
255 memcpy(ies.ie_hopping_sequence_list, tsch_hopping_sequence,
256 ies.ie_hopping_sequence_len);
261 #if TSCH_PACKET_EB_WITH_SLOTFRAME_AND_LINK 267 ies.ie_tsch_slotframe_and_link.num_slotframes = 1;
268 ies.ie_tsch_slotframe_and_link.slotframe_handle = sf0->handle;
269 ies.ie_tsch_slotframe_and_link.slotframe_size = sf0->size.val;
270 ies.ie_tsch_slotframe_and_link.num_links = 1;
271 ies.ie_tsch_slotframe_and_link.links[0].timeslot = link0->timeslot;
272 ies.ie_tsch_slotframe_and_link.links[0].channel_offset =
273 link0->channel_offset;
274 ies.ie_tsch_slotframe_and_link.links[0].link_options =
282 ie_len = frame80215e_create_ie_tsch_synchronization(p,
291 ie_len = frame80215e_create_ie_tsch_timeslot(p,
300 ie_len = frame80215e_create_ie_tsch_channel_hopping_sequence(p,
309 ie_len = frame80215e_create_ie_tsch_slotframe_and_link(p,
320 ie_len = frame80215e_create_ie_payload_list_termination(p,
345 ie_len = frame80215e_create_ie_header_list_termination_1(
packetbuf_hdrptr(),
352 packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_BEACONFRAME);
353 packetbuf_set_attr(PACKETBUF_ATTR_MAC_METADATA, 1);
356 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &tsch_eb_address);
358 #if LLSEC802154_ENABLED 359 if(tsch_is_pan_secured) {
360 packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL,
361 TSCH_SECURITY_KEY_SEC_LEVEL_EB);
362 packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE,
363 FRAME802154_1_BYTE_KEY_ID_MODE);
364 packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX,
365 TSCH_SECURITY_KEY_INDEX_EB);
369 if(NETSTACK_FRAMER.create() < 0) {
373 if(hdr_len != NULL) {
382 if(tsch_sync_ie_offset != NULL) {
393 struct ieee802154_ies ies;
394 ies.ie_asn = tsch_current_asn;
395 ies.ie_join_priority = tsch_join_priority;
396 return frame80215e_create_ie_tsch_synchronization(buf+tsch_sync_ie_offset, buf_size-tsch_sync_ie_offset, &ies) != -1;
402 frame802154_t *frame,
struct ieee802154_ies *ies, uint8_t *hdr_len,
int frame_without_mic)
404 uint8_t curr_len = 0;
407 if(frame == NULL || buf_size < 0) {
413 LOG_ERR(
"! parse_eb: failed to parse frame\n");
419 LOG_INFO(
"! parse_eb: frame is not a valid TSCH beacon. Frame version %u, type %u, FCF %02x %02x\n",
421 LOG_INFO(
"! parse_eb: frame was from 0x%x/", frame->
src_pid);
422 LOG_INFO_LLADDR((
const linkaddr_t *)&frame->
src_addr);
423 LOG_INFO_(
" to 0x%x/", frame->
dest_pid);
424 LOG_INFO_LLADDR((
const linkaddr_t *)&frame->
dest_addr);
429 if(hdr_len != NULL) {
435 memset(ies, 0,
sizeof(
struct ieee802154_ies));
436 ies->ie_join_priority = 0xff;
441 #if LLSEC802154_ENABLED 442 if(!frame_without_mic) {
444 if(buf_size < curr_len + mic_len) {
451 if((ret = frame802154e_parse_information_elements(buf + curr_len, buf_size - curr_len - mic_len, ies)) == -1) {
452 LOG_ERR(
"! parse_eb: failed to parse IEs\n");
458 if(hdr_len != NULL) {
459 *hdr_len += ies->ie_payload_ie_offset;
469 buf[0] |= (1 << IEEE802154_FRAME_PENDING_BIT_OFFSET);
476 return (buf[0] >> IEEE802154_FRAME_PENDING_BIT_OFFSET) & 1;
uint16_t src_pid
Source PAN ID.
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
int tsch_packet_create_eb(uint8_t *hdr_len, uint8_t *tsch_sync_ie_offset)
Create an EB packet directly in packetbuf.
frame802154_fcf_t fcf
Frame control field.
void packetbuf_clear(void)
Clear and reset the packetbuf.
int packetbuf_hdralloc(int size)
Extend the header of the packetbuf, for outbound packets.
uint16_t packetbuf_remaininglen(void)
Get the total length of the remaining space in the packetbuf.
int frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
Parses an input frame.
802.15.4e slotframe (contains links)
uint8_t packetbuf_hdrlen(void)
Get the length of the header in the packetbuf.
struct tsch_link * tsch_schedule_get_link_by_timeslot(struct tsch_slotframe *slotframe, uint16_t timeslot)
Looks within a slotframe for a link with a given timeslot.
uint8_t src_addr[8]
Source address.
int frame802154_hdrlen(frame802154_t *p)
Calculates the length of the frame header.
A MAC framer for IEEE 802.15.4
const linkaddr_t linkaddr_null
The null link-layer address.
int tsch_packet_update_eb(uint8_t *buf, int buf_size, uint8_t tsch_sync_ie_offset)
Update ASN in EB packet.
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
linkaddr_t linkaddr_node_addr
The link-layer address of the node.
struct tsch_slotframe * tsch_schedule_get_slotframe_by_handle(uint16_t handle)
Looks up a slotframe by handle.
unsigned int tsch_security_mic_len(const frame802154_t *frame)
Return MIC length.
uint8_t frame_version
2 bit.
uint16_t packetbuf_totlen(void)
Get the total length of the header and data in the packetbuf.
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)
Parse enhanced ACK packet.
Main API declarations for TSCH.
802.15.4 frame creation and parsing functions
uint16_t dest_pid
Destination PAN ID.
Parameters used by the frame802154_create() function.
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a link-layer address.
void tsch_packet_set_frame_pending(uint8_t *buf, int buf_size)
Set frame pending bit in a packet (whose header was already build)
int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two link-layer addresses.
void * packetbuf_hdrptr(void)
Get a pointer to the header in the packetbuf, for outbound packets.
uint8_t ie_list_present
1 bit.
uint8_t seq
Sequence number.
int tsch_packet_get_frame_pending(uint8_t *buf, int buf_size)
Get frame pending bit from a packet.
An IEEE 802.15.4-2015 TSCH link (also called cell or slot)
Header file for the Packet buffer (packetbuf) management
Include file for the Contiki low-layer network stack (NETSTACK)
uint8_t dest_addr[8]
Destination address.
Header file for the logging system
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)
Parse EB.
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
int frame80215e_create_ie_header_ack_nack_time_correction(uint8_t *buf, int len, struct ieee802154_ies *ies)
Insert various Information Elements.
int frame802154_create(frame802154_t *p, uint8_t *buf)
Creates a frame for transmission over the air.
int tsch_packet_create_eack(uint8_t *buf, uint16_t buf_len, const linkaddr_t *dest_addr, uint8_t seqno, int16_t drift, int nack)
Construct Enhanced ACK packet.