/*---------------------------------------------------------------------------*/ static int parse(void) { frame802154_t frame; int len; len = packetbuf_datalen(); if(frame802154_parse(packetbuf_dataptr(), len, &frame)) { if(frame.fcf.dest_addr_mode) { if(frame.dest_pid != mac_src_pan_id && frame.dest_pid != FRAME802154_BROADCASTPANDID) { /* Packet to another PAN */ PRINTF("15.4: for another pan %u\n", frame.dest_pid); return 0; } if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (linkaddr_t *)&frame.dest_addr); } } packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (linkaddr_t *)&frame.src_addr); packetbuf_set_attr(PACKETBUF_ATTR_PENDING, frame.fcf.frame_pending); packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, frame.seq); PRINTF("15.4-IN: %2X", frame.fcf.frame_type); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); PRINTF("%u (%u)\n", packetbuf_datalen(), len); return 0; } return 0; }
/*---------------------------------------------------------------------------*/ static int parse(void) { frame802154_t frame; int len; len = packetbuf_datalen(); if(frame802154_parse(packetbuf_dataptr(), len, &frame) && packetbuf_hdrreduce(len - frame.payload_len)) { if(frame.fcf.dest_addr_mode) { if(frame.dest_pid != mac_src_pan_id && frame.dest_pid != FRAME802154_BROADCASTPANDID) { /* Packet to another PAN */ PRINTF("15.4: for another pan %u\n", frame.dest_pid); return FRAMER_FAILED; } if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (linkaddr_t *)&frame.dest_addr); } } packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (linkaddr_t *)&frame.src_addr); packetbuf_set_attr(PACKETBUF_ATTR_PENDING, frame.fcf.frame_pending); /* packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, frame.fcf.ack_required);*/ packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, frame.seq); PRINTF("15.4-IN: %2X", frame.fcf.frame_type); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); PRINTF("%u (%u)\n", packetbuf_datalen(), len); return len - frame.payload_len; } return FRAMER_FAILED; }
/* Check if a packet is for us */ static int is_packet_for_us(uint8_t *buf, int len, int do_send_ack) { frame802154_t frame; int result; uint8_t parsed = frame802154_parse(buf, len, &frame); if(parsed) { if(frame.fcf.dest_addr_mode) { int has_dest_panid; frame802154_has_panid(&frame.fcf, NULL, &has_dest_panid); if(has_dest_panid && frame802154_get_pan_id() != FRAME802154_BROADCASTPANDID && frame.dest_pid != frame802154_get_pan_id() && frame.dest_pid != FRAME802154_BROADCASTPANDID) { /* Packet to another PAN */ return 0; } if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { result = linkaddr_cmp((linkaddr_t *)frame.dest_addr, &linkaddr_node_addr); if(autoack_enabled && result && do_send_ack) { /* this is a unicast frame and sending ACKs is enabled */ send_ack(&frame); } return result; } } return 1; } else { return 0; } }
/* Process pending input packet(s) */ static void tsch_rx_process_pending() { int16_t input_index; /* Loop on accessing (without removing) a pending input packet */ while((input_index = ringbufindex_peek_get(&input_ringbuf)) != -1) { struct input_packet *current_input = &input_array[input_index]; frame802154_t frame; uint8_t ret = frame802154_parse(current_input->payload, current_input->len, &frame); int is_data = ret && frame.fcf.frame_type == FRAME802154_DATAFRAME; int is_eb = ret && frame.fcf.frame_version == FRAME802154_IEEE802154E_2012 && frame.fcf.frame_type == FRAME802154_BEACONFRAME; if(is_data) { /* Skip EBs and other control messages */ /* Copy to packetbuf for processing */ packetbuf_copyfrom(current_input->payload, current_input->len); packetbuf_set_attr(PACKETBUF_ATTR_RSSI, current_input->rssi); } /* Remove input from ringbuf */ ringbufindex_get(&input_ringbuf); if(is_data) { /* Pass to upper layers */ packet_input(); } else if(is_eb) { eb_input(current_input); } } }
/*---------------------------------------------------------------------------*/ static int parse(struct net_buf *buf) { frame802154_t frame; int hdr_len; hdr_len = frame802154_parse(packetbuf_dataptr(buf), packetbuf_datalen(buf), &frame); if(hdr_len && packetbuf_hdrreduce(buf, hdr_len)) { packetbuf_set_attr(buf, PACKETBUF_ATTR_FRAME_TYPE, frame.fcf.frame_type); if(frame.fcf.dest_addr_mode) { if(frame.dest_pid != mac_src_pan_id && frame.dest_pid != FRAME802154_BROADCASTPANDID) { /* Packet to another PAN */ PRINTF("15.4: for another pan %u (0x%x)\n", frame.dest_pid, frame.dest_pid); return FRAMER_FAILED; } if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { packetbuf_set_addr(buf, PACKETBUF_ADDR_RECEIVER, (linkaddr_t *)&frame.dest_addr); } } packetbuf_set_addr(buf, PACKETBUF_ADDR_SENDER, (linkaddr_t *)&frame.src_addr); packetbuf_set_attr(buf, PACKETBUF_ATTR_PENDING, frame.fcf.frame_pending); /* packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, frame.fcf.ack_required);*/ packetbuf_set_attr(buf, PACKETBUF_ATTR_PACKET_ID, frame.seq); #if LLSEC802154_SECURITY_LEVEL if(frame.fcf.security_enabled) { packetbuf_set_attr(buf, PACKETBUF_ATTR_SECURITY_LEVEL, frame.aux_hdr.security_control.security_level); packetbuf_set_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, frame.aux_hdr.frame_counter.u16[0]); packetbuf_set_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, frame.aux_hdr.frame_counter.u16[1]); #if LLSEC802154_USES_EXPLICIT_KEYS packetbuf_set_attr(buf, PACKETBUF_ATTR_KEY_ID_MODE, frame.aux_hdr.security_control.key_id_mode); packetbuf_set_attr(buf, PACKETBUF_ATTR_KEY_INDEX, frame.aux_hdr.key_index); packetbuf_set_attr(buf, PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1, frame.aux_hdr.key_source.u16[0]); #endif /* LLSEC802154_USES_EXPLICIT_KEYS */ } #endif /* LLSEC802154_SECURITY_LEVEL */ PRINTF("15.4-IN: %2X ", frame.fcf.frame_type); PRINTLLADDR((const uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_SENDER)); PRINTF(" "); PRINTLLADDR((const uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER)); PRINTF(" %d %u (%u)\n", hdr_len, packetbuf_datalen(buf), packetbuf_totlen(buf)); #ifdef FRAMER_802154_HANDLER if(FRAMER_802154_HANDLER(&frame)) { return FRAMER_FRAME_HANDLED; } #endif return hdr_len; } return FRAMER_FAILED; }
/*---------------------------------------------------------------------------*/ static int parse(void) { frame802154_t frame; int hdr_len; hdr_len = frame802154_parse(packetbuf_dataptr(), packetbuf_datalen(), &frame); if(hdr_len && packetbuf_hdrreduce(hdr_len)) { packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, frame.fcf.frame_type); if(frame.fcf.dest_addr_mode) { if(frame.dest_pid != frame802154_get_pan_id() && frame.dest_pid != FRAME802154_BROADCASTPANDID) { /* Packet to another PAN */ PRINTF("15.4: for another pan %u\n", frame.dest_pid); return FRAMER_FAILED; } if(!frame802154_is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (linkaddr_t *)&frame.dest_addr); } } packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (linkaddr_t *)&frame.src_addr); packetbuf_set_attr(PACKETBUF_ATTR_PENDING, frame.fcf.frame_pending); if(frame.fcf.sequence_number_suppression == 0) { packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, frame.seq); } else { packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, 0xffff); } #if NETSTACK_CONF_WITH_RIME packetbuf_set_attr(PACKETBUF_ATTR_PACKET_ID, frame.seq); #endif #if LLSEC802154_USES_AUX_HEADER if(frame.fcf.security_enabled) { packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, frame.aux_hdr.security_control.security_level); #if LLSEC802154_USES_FRAME_COUNTER packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, frame.aux_hdr.frame_counter.u16[0]); packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, frame.aux_hdr.frame_counter.u16[1]); #endif /* LLSEC802154_USES_FRAME_COUNTER */ #if LLSEC802154_USES_EXPLICIT_KEYS packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, frame.aux_hdr.security_control.key_id_mode); packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX, frame.aux_hdr.key_index); packetbuf_set_attr(PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1, frame.aux_hdr.key_source.u16[0]); #endif /* LLSEC802154_USES_EXPLICIT_KEYS */ } #endif /* LLSEC802154_USES_AUX_HEADER */ PRINTF("15.4-IN: %2X", frame.fcf.frame_type); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); PRINTF("%d %u (%u)\n", hdr_len, packetbuf_datalen(), packetbuf_totlen()); return hdr_len; } return FRAMER_FAILED; }
//#define DISPATCH_BYTE_POS 0 //#define 802154_CMDFRM_ID_POS 0 static void lowpan_packet_input(void) { //uint8_t * rime_ptr = NULL; frame802154_t frame; // TODO: BSKR is this buflen and not len?? frame802154_parse(packetbuf_dataptr(), packetbuf_datalen(), &frame); #ifdef LOWPAN_COORDINATOR mac_proc_pkt(&frame); #else mac_proc_state(&frame); #endif }
/*---------------------------------------------------------------------------*/ static uint8_t input_packet(struct net_buf *buf) { frame802154_t frame; int len; len = packetbuf_datalen(buf); PRINTF("6MAC: received %d bytes\n", len); if(frame802154_parse(packetbuf_dataptr(buf), len, &frame) && packetbuf_hdrreduce(buf, len - frame.payload_len)) { if(frame.fcf.dest_addr_mode) { if(frame.dest_pid != mac_src_pan_id && frame.dest_pid != FRAME802154_BROADCASTPANDID) { /* Not broadcast or for our PAN */ PRINTF("6MAC: for another pan %u (0x%x)\n", frame.dest_pid, frame.dest_pid); goto error; } if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { packetbuf_set_addr(buf, PACKETBUF_ADDR_RECEIVER, (linkaddr_t *)&frame.dest_addr); #if !NETSTACK_CONF_BRIDGE_MODE if(!linkaddr_cmp(packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER), &linkaddr_node_addr)) { /* Not for this node */ PRINTF("6MAC: not for us, we are "); PRINTLLADDR((uip_lladdr_t *)&linkaddr_node_addr); PRINTF(" recipient is "); PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER)); PRINTF("\n"); goto error; } #endif } } packetbuf_set_addr(buf, PACKETBUF_ADDR_SENDER, (linkaddr_t *)&frame.src_addr); PRINTF("6MAC-IN: type 0x%X sender ", frame.fcf.frame_type); PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_SENDER)); PRINTF(" receiver "); PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER)); PRINTF(" len %u\n", packetbuf_datalen(buf)); return NETSTACK_MAC.input(buf); } else { PRINTF("6MAC: failed to parse hdr\n"); } error: return 0; }
/*---------------------------------------------------------------------------*/ static int read_packet(void) { frame802154_t frame; int len; packetbuf_clear(); len = radio->read(packetbuf_dataptr(), PACKETBUF_SIZE); if(len > 0) { packetbuf_set_datalen(len); if(frame802154_parse(packetbuf_dataptr(), len, &frame) && packetbuf_hdrreduce(len - frame.payload_len)) { if(frame.fcf.dest_addr_mode) { if(frame.dest_pid != mac_src_pan_id && frame.dest_pid != FRAME802154_BROADCASTPANDID) { /* Not broadcast or for our PAN */ PRINTF("6MAC: for another pan %u\n", frame.dest_pid); return 0; } if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr.u8)) { packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &frame.dest_addr); if(!rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_node_addr)) { /* Not for this node */ PRINTF("6MAC: not for us\n"); return 0; } } } packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &frame.src_addr); #if MAC_FILTER if(mac_filter()){ PRINTF("Filter dropped a packet!"); return -1; } #endif PRINTF("6MAC-IN: %2X", frame.fcf.frame_type); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); PRINTF("%u\n", packetbuf_datalen()); return packetbuf_datalen(); } else { PRINTF("6MAC: failed to parse hdr\n"); } } return 0; }
/*---------------------------------------------------------------------------*/ static void input_packet(void) { frame802154_t frame; int len; len = packetbuf_datalen(); if(frame802154_parse(packetbuf_dataptr(), len, &frame) && packetbuf_hdrreduce(len - frame.payload_len)) { if(frame.fcf.dest_addr_mode) { if(frame.dest_pid != mac_src_pan_id && frame.dest_pid != FRAME802154_BROADCASTPANDID) { /* Not broadcast or for our PAN */ PRINTF("6MAC: for another pan %u\n", frame.dest_pid); return; } if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (rimeaddr_t *)&frame.dest_addr); if(!rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_node_addr)) { /* Not for this node */ PRINTF("6MAC: not for us\n"); return; } } } packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (rimeaddr_t *)&frame.src_addr); PRINTF("6MAC-IN: %2X", frame.fcf.frame_type); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER)); printf("\n\n!Incoming Data %u!\n\n", packetbuf_datalen()); NETSTACK_MAC.input(); } else { PRINTF("6MAC: failed to parse hdr\n"); } }
/*---------------------------------------------------------------------------*/ static int spirit_radio_prepare(const void *payload, unsigned short payload_len) { PRINTF("Spirit1: prep %u\n", payload_len); packet_is_prepared = 0; /* Checks if the payload length is supported */ if(payload_len > MAX_PACKET_LEN) { return RADIO_TX_ERR; } /* Waits the end of a still running spirit_radio_transmit */ BUSYWAIT_UNTIL(IS_TXBUF_EMPTY(), TX_WAIT_PCKT_PERIOD * RTIMER_SECOND/1000); if(!IS_TXBUF_EMPTY()) { PRINTF("PREPARE OUT ERR\n"); return RADIO_TX_ERR; } /* Should we delay for an ack? */ #if NULLRDC_CONF_802154_AUTOACK frame802154_t info154; wants_an_ack = 0; if(payload_len > ACK_LEN && frame802154_parse((char*)payload, payload_len, &info154) != 0) { if(info154.fcf.frame_type == FRAME802154_DATAFRAME && info154.fcf.ack_required != 0) { wants_an_ack = 1; } } #endif /* NULLRDC_CONF_802154_AUTOACK */ /* Sets the length of the packet to send */ spirit1_strobe(SPIRIT1_STROBE_FTX); SpiritPktBasicSetPayloadLength(payload_len); SpiritSpiWriteLinearFifo(payload_len, (uint8_t *)payload); PRINTF("PREPARE OUT\n"); packet_is_prepared = 1; return RADIO_TX_OK; }
static inline bool send_ack_packet(struct net_buf *buf, uint8_t *status) { struct net_buf *ack_buf; frame802154_t frame; if (packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_TYPE) != FRAME802154_DATAFRAME) { return false; } frame802154_parse(packetbuf_dataptr(buf), packetbuf_datalen(buf), &frame); if (frame.fcf.ack_required == 0 || !linkaddr_cmp((linkaddr_t *)&frame.dest_addr, &linkaddr_node_addr)) { return false; } ack_buf = l2_buf_get_reserve(0); if (!ack_buf) { *status = MAC_TX_ERR; return false; } uip_pkt_packetbuf(ack_buf)[0] = FRAME802154_ACKFRAME; uip_pkt_packetbuf(ack_buf)[1] = 0; uip_pkt_packetbuf(ack_buf)[2] = frame.seq; *status = NETSTACK_RADIO.send(ack_buf, NULL, ACK_LEN); l2_buf_unref(ack_buf); PRINTF("simplerdc: Send ACK to packet %u\n", packetbuf_attr(buf, PACKETBUF_ATTR_MAC_SEQNO)); return true; }
/*---------------------------------------------------------------------------*/ static void packet_input(void) { radio_value_t channel; #if NULLRDC_SEND_802154_ACK int original_datalen; uint8_t *original_dataptr; original_datalen = packetbuf_datalen(); original_dataptr = packetbuf_dataptr(); #endif NETSTACK_RADIO.get_value(RADIO_PARAM_CHANNEL, &channel); packetbuf_set_attr(PACKETBUF_ATTR_CHANNEL, channel); #if NULLRDC_802154_AUTOACK if(packetbuf_datalen() == ACK_LEN) { /* Ignore ack packets */ PRINTF("nullrdc: ignored ack\n"); } else #endif /* NULLRDC_802154_AUTOACK */ if(NETSTACK_FRAMER.parse() < 0) { PRINTF("nullrdc: failed to parse %u\n", packetbuf_datalen()); #if NULLRDC_ADDRESS_FILTER } else if(!linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_node_addr) && !packetbuf_holds_broadcast()) { PRINTF("nullrdc: not for us\n"); #endif /* NULLRDC_ADDRESS_FILTER */ } else { int duplicate = 0; #if NULLRDC_802154_AUTOACK || NULLRDC_802154_AUTOACK_HW #if RDC_WITH_DUPLICATE_DETECTION /* Check for duplicate packet. */ duplicate = mac_sequence_is_duplicate(); if(duplicate) { /* Drop the packet. */ PRINTF("nullrdc: drop duplicate link layer packet %u\n", packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO)); } else { mac_sequence_register_seqno(); } #endif /* RDC_WITH_DUPLICATE_DETECTION */ #endif /* NULLRDC_802154_AUTOACK */ /* TODO We may want to acknowledge only authentic frames */ #if NULLRDC_SEND_802154_ACK { frame802154_t info154; frame802154_parse(original_dataptr, original_datalen, &info154); if(info154.fcf.frame_type == FRAME802154_DATAFRAME && info154.fcf.ack_required != 0 && linkaddr_cmp((linkaddr_t *)&info154.dest_addr, &linkaddr_node_addr)) { uint8_t ackdata[ACK_LEN] = {0, 0, 0}; ackdata[0] = FRAME802154_ACKFRAME; ackdata[1] = 0; ackdata[2] = info154.seq; NETSTACK_RADIO.send(ackdata, ACK_LEN); } } #endif /* NULLRDC_SEND_ACK */ if(!duplicate) { NETSTACK_MAC.input(); } } }
/*---------------------------------------------------------------------------*/ static void input_packet(void) { static struct ctimer ct; int duplicate = 0; #if CONTIKIMAC_SEND_SW_ACK int original_datalen; uint8_t *original_dataptr; original_datalen = packetbuf_datalen(); original_dataptr = packetbuf_dataptr(); #endif if(!we_are_receiving_burst) { off(); } if(packetbuf_datalen() == ACK_LEN) { /* Ignore ack packets */ PRINTF("ContikiMAC: ignored ack\n"); return; } /* printf("cycle_start 0x%02x 0x%02x\n", cycle_start, cycle_start % CYCLE_TIME);*/ if(packetbuf_totlen() > 0 && NETSTACK_FRAMER.parse() >= 0) { if(packetbuf_datalen() > 0 && packetbuf_totlen() > 0 && (linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_node_addr) || packetbuf_holds_broadcast())) { /* This is a regular packet that is destined to us or to the broadcast address. */ /* If FRAME_PENDING is set, we are receiving a packets in a burst */ we_are_receiving_burst = packetbuf_attr(PACKETBUF_ATTR_PENDING); if(we_are_receiving_burst) { on(); /* Set a timer to turn the radio off in case we do not receive a next packet */ ctimer_set(&ct, INTER_PACKET_DEADLINE, recv_burst_off, NULL); } else { off(); ctimer_stop(&ct); } #if RDC_WITH_DUPLICATE_DETECTION /* Check for duplicate packet. */ duplicate = mac_sequence_is_duplicate(); if(duplicate) { /* Drop the packet. */ PRINTF("contikimac: Drop duplicate\n"); } else { mac_sequence_register_seqno(); } #endif /* RDC_WITH_DUPLICATE_DETECTION */ #if CONTIKIMAC_CONF_COMPOWER /* Accumulate the power consumption for the packet reception. */ compower_accumulate(¤t_packet); /* Convert the accumulated power consumption for the received packet to packet attributes so that the higher levels can keep track of the amount of energy spent on receiving the packet. */ compower_attrconv(¤t_packet); /* Clear the accumulated power consumption so that it is ready for the next packet. */ compower_clear(¤t_packet); #endif /* CONTIKIMAC_CONF_COMPOWER */ PRINTDEBUG("contikimac: data (%u)\n", packetbuf_datalen()); #if CONTIKIMAC_SEND_SW_ACK { frame802154_t info154; frame802154_parse(original_dataptr, original_datalen, &info154); if(info154.fcf.frame_type == FRAME802154_DATAFRAME && info154.fcf.ack_required != 0 && linkaddr_cmp((linkaddr_t *)&info154.dest_addr, &linkaddr_node_addr)) { uint8_t ackdata[ACK_LEN] = {0, 0, 0}; we_are_sending = 1; ackdata[0] = FRAME802154_ACKFRAME; ackdata[1] = 0; ackdata[2] = info154.seq; NETSTACK_RADIO.send(ackdata, ACK_LEN); we_are_sending = 0; } } #endif /* CONTIKIMAC_SEND_SW_ACK */ if(!duplicate) { NETSTACK_MAC.input(); } return; } else { PRINTDEBUG("contikimac: data not for us\n"); } } else { PRINTF("contikimac: failed to parse (%u)\n", packetbuf_totlen()); } }
/*---------------------------------------------------------------------------*/ static uint8_t packet_input(struct net_buf *buf) { #if NULLRDC_SEND_802154_ACK int original_datalen; uint8_t *original_dataptr; original_datalen = packetbuf_datalen(buf); original_dataptr = packetbuf_dataptr(buf); #endif #if NULLRDC_802154_AUTOACK if(packetbuf_datalen(buf) == ACK_LEN) { /* Ignore ack packets */ PRINTF("nullrdc: ignored ack\n"); } else #endif /* NULLRDC_802154_AUTOACK */ if(NETSTACK_FRAMER.parse(buf) < 0) { PRINTF("nullrdc: failed to parse msg len %u\n", packetbuf_datalen(buf)); #if NULLRDC_ADDRESS_FILTER } else if(!linkaddr_cmp(packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER), &linkaddr_node_addr) && !packetbuf_holds_broadcast(buf)) { PRINTF("nullrdc: not for us\n"); #endif /* NULLRDC_ADDRESS_FILTER */ } else { int duplicate = 0; #if NULLRDC_802154_AUTOACK || NULLRDC_802154_AUTOACK_HW /* If llsec is not doing anti replay checks this needs to be done */ if(anti_replay_is_anti_replay_checked(buf) == 0) { /* Check for duplicate packet. */ duplicate = mac_sequence_is_duplicate(buf); if(duplicate) { /* Drop the packet. */ PRINTF("nullrdc: drop duplicate link layer packet %u\n", packetbuf_attr(buf, PACKETBUF_ATTR_MAC_SEQNO)); } else { mac_sequence_register_seqno(buf); } } #endif /* NULLRDC_802154_AUTOACK */ /* TODO We may want to acknowledge only authentic frames */ #if NULLRDC_SEND_802154_ACK { frame802154_t info154; frame802154_parse(original_dataptr, original_datalen, &info154); if(info154.fcf.frame_type == FRAME802154_DATAFRAME && info154.fcf.ack_required != 0 && linkaddr_cmp((linkaddr_t *)&info154.dest_addr, &linkaddr_node_addr)) { uint8_t ackdata[ACK_LEN] = {0, 0, 0}; ackdata[0] = FRAME802154_ACKFRAME; ackdata[1] = 0; ackdata[2] = info154.seq; return NETSTACK_RADIO.send(ackdata, ACK_LEN); } } #endif /* NULLRDC_SEND_ACK */ if(!duplicate) { return NETSTACK_MAC.input(buf); } } return 0; }
/*---------------------------------------------------------------------------*/ static void packet_input(void) { int original_datalen; uint8_t *original_dataptr; original_datalen = packetbuf_datalen(); original_dataptr = packetbuf_dataptr(); #ifdef NETSTACK_DECRYPT NETSTACK_DECRYPT(); #endif /* NETSTACK_DECRYPT */ #if NULLRDC_802154_AUTOACK if(packetbuf_datalen() == ACK_LEN) { /* Ignore ack packets */ PRINTF("nullrdc: ignored ack\n"); } else #endif /* NULLRDC_802154_AUTOACK */ if(NETSTACK_FRAMER.parse() < 0) { PRINTF("nullrdc: failed to parse %u\n", packetbuf_datalen()); #if NULLRDC_ADDRESS_FILTER } else if(!linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_node_addr) && !linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) { PRINTF("nullrdc: not for us\n"); #endif /* NULLRDC_ADDRESS_FILTER */ } else { int duplicate = 0; #if NULLRDC_802154_AUTOACK || NULLRDC_802154_AUTOACK_HW /* Check for duplicate packet. */ duplicate = mac_sequence_is_duplicate(); if(duplicate) { /* Drop the packet. */ PRINTF("nullrdc: drop duplicate link layer packet %u\n", packetbuf_attr(PACKETBUF_ATTR_PACKET_ID)); } else { mac_sequence_register_seqno(); } #endif /* NULLRDC_802154_AUTOACK */ #if NULLRDC_SEND_802154_ACK { frame802154_t info154; frame802154_parse(original_dataptr, original_datalen, &info154); if(info154.fcf.frame_type == FRAME802154_DATAFRAME && info154.fcf.ack_required != 0 && linkaddr_cmp((linkaddr_t *)&info154.dest_addr, &linkaddr_node_addr)) { uint8_t ackdata[ACK_LEN] = {0, 0, 0}; ackdata[0] = FRAME802154_ACKFRAME; ackdata[1] = 0; ackdata[2] = info154.seq; NETSTACK_RADIO.send(ackdata, ACK_LEN); } } #endif /* NULLRDC_SEND_ACK */ if(!duplicate) { NETSTACK_MAC.input(); } } }
/*---------------------------------------------------------------------------*/ static int input_byte(uint8_t byte) { int crc; if(timer_expired(&rxstate.timer)) { restart_input(); } PT_BEGIN(&rxstate.pt); /* The first incoming byte is the length of the packet. */ rxstate.receiving = 1; rxstate.len = byte; if(byte == 0) { #if DEBUG printf("Bad len 0, state %d rxbytes %d\n", state(), read_rxbytes()); #endif /* DEBUG */ flushrx(); PT_EXIT(&rxstate.pt); } timer_set(&rxstate.timer, PACKET_LIFETIME); for(rxstate.ptr = 0; rxstate.ptr < rxstate.len; rxstate.ptr++) { /* Wait for the next data byte to be received. */ PT_YIELD(&rxstate.pt); rxstate.buf[rxstate.ptr] = byte; } /* Receive two more bytes from the FIFO: the RSSI value and the LQI/CRC */ PT_YIELD(&rxstate.pt); rxstate.buf[rxstate.ptr] = byte; rxstate.ptr++; PT_YIELD(&rxstate.pt); rxstate.buf[rxstate.ptr] = byte; crc = (byte & 0x80); rxstate.ptr++; if(crc == 0) { #if DEBUG printf("bad crc\n"); #endif /* DEBUG */ flushrx(); } else if(packet_rx_len > 0) { #if DEBUG printf("Packet in the buffer (%d), dropping %d bytes\n", packet_rx_len, rxstate.len); #endif /* DEBUG */ flushrx(); process_poll(&cc1101_process); } else if(rxstate.len < ACK_LEN) { /* Drop packets that are way too small: less than ACK_LEN (3) bytes long. */ #if DEBUG printf("!"); #endif /* DEBUG */ } else { /* Read out the first three bytes to determine if we should send an ACK or not. */ /* Send a link-layer ACK before reading the full packet. */ if(rxstate.len >= ACK_LEN) { /* Try to parse the incoming frame as a 802.15.4 header. */ frame802154_t info154; if(frame802154_parse(rxstate.buf, rxstate.len, &info154) != 0) { /* XXX Potential optimization here: we could check if the frame is destined for us, or for the broadcast address and discard the packet if it isn't for us. */ if(1) { /* For dataframes that has the ACK request bit set and that is destined for us, we send an ack. */ if(info154.fcf.frame_type == FRAME802154_DATAFRAME && info154.fcf.ack_required != 0 && rimeaddr_cmp((rimeaddr_t *)&info154.dest_addr, &rimeaddr_node_addr)) { send_ack(info154.seq); /* Make sure that we don't put the radio in the IDLE state before the ACK has been fully transmitted. */ BUSYWAIT_UNTIL((state() != CC1101_STATE_TX), RTIMER_SECOND / 10); ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); ENERGEST_ON(ENERGEST_TYPE_LISTEN); if(state() == CC1101_STATE_TX) { #if DEBUG printf("didn't end ack tx (in %d, txbytes %d)\n", state(), txbytes()); #endif /* DEBUG */ check_txfifo(); flushrx(); } } memcpy((void *)packet_rx, rxstate.buf, rxstate.len + AUX_LEN); packet_rx_len = rxstate.len + AUX_LEN; /* including AUX */ process_poll(&cc1101_process); #if DEBUG printf("#"); #endif /* DEBUG */ } } } } rxstate.receiving = 0; PT_END(&rxstate.pt); }
PROCESS_THREAD(spirit_radio_process, ev, data) { PROCESS_BEGIN(); PRINTF("Spirit1: process started\n"); while(1) { int len; PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); PRINTF("Spirit1: polled\n"); packetbuf_clear(); len = spirit_radio_read(packetbuf_dataptr(), PACKETBUF_SIZE); if(len > 0) { #if NULLRDC_CONF_802154_AUTOACK /* Check if the packet has an ACK request */ frame802154_t info154; if(len > ACK_LEN && frame802154_parse((char*)packetbuf_dataptr(), len, &info154) != 0) { if(info154.fcf.frame_type == FRAME802154_DATAFRAME && info154.fcf.ack_required != 0 && rimeaddr_cmp((rimeaddr_t *)&info154.dest_addr, &rimeaddr_node_addr)) { /* Send an ACK packet */ uint8_t ack_frame[ACK_LEN] = { FRAME802154_ACKFRAME, 0x00, info154.seq }; spirit1_strobe(SPIRIT1_STROBE_FTX); SpiritPktBasicSetPayloadLength((uint16_t) ACK_LEN); SpiritSpiWriteLinearFifo((uint16_t) ACK_LEN, (uint8_t *) ack_frame); SpiritSetReadyState(); spirit1_strobe(SPIRIT1_STROBE_TX); BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_TX, 1 * RTIMER_SECOND/1000); BUSYWAIT_UNTIL(SPIRIT1_STATUS() != SPIRIT1_STATE_TX, 1 * RTIMER_SECOND/1000); ACKPRINTF("debug_ack: sent ack %d\n", ack_frame[2]); } } #endif /* NULLRDC_CONF_802154_AUTOACK */ packetbuf_set_datalen(len); NETSTACK_RDC.input(); } if(!IS_RXBUF_EMPTY()){ process_poll(&spirit_radio_process); } if(interrupt_callback_wants_poll) { spirit1_interrupt_callback(); if(SPIRIT1_STATUS() == SPIRIT1_STATE_READY) { spirit1_strobe(SPIRIT1_STROBE_RX); BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 1 * RTIMER_SECOND/1000); } } } PROCESS_END(); }
/* Parse a IEEE 802.15.4e TSCH Enhanced Beacon (EB) */ int tsch_packet_parse_eb(const uint8_t *buf, int buf_size, frame802154_t *frame, struct ieee802154_ies *ies, uint8_t *hdr_len, int frame_without_mic) { uint8_t curr_len = 0; int ret; if(frame == NULL || buf_size < 0) { return 0; } /* Parse 802.15.4-2006 frame, i.e. all fields before Information Elements */ if((ret = frame802154_parse((uint8_t *)buf, buf_size, frame)) == 0) { PRINTF("TSCH:! parse_eb: failed to parse frame\n"); return 0; } if(frame->fcf.frame_version < FRAME802154_IEEE802154E_2012 || frame->fcf.frame_type != FRAME802154_BEACONFRAME) { PRINTF("TSCH:! parse_eb: frame is not a valid TSCH beacon. Frame version %u, type %u, FCF %02x %02x\n", frame->fcf.frame_version, frame->fcf.frame_type, buf[0], buf[1]); PRINTF("TSCH:! parse_eb: frame was from 0x%x/", frame->src_pid); PRINTLLADDR((const uip_lladdr_t *)&frame->src_addr); PRINTF(" to 0x%x/", frame->dest_pid); PRINTLLADDR((const uip_lladdr_t *)&frame->dest_addr); PRINTF("\n"); return 0; } if(hdr_len != NULL) { *hdr_len = ret; } curr_len += ret; if(ies != NULL) { memset(ies, 0, sizeof(struct ieee802154_ies)); ies->ie_join_priority = 0xff; /* Use max value in case the Beacon does not include a join priority */ } if(frame->fcf.ie_list_present) { /* Calculate space needed for the security MIC, if any, before attempting to parse IEs */ int mic_len = 0; #if LLSEC802154_ENABLED if(!frame_without_mic) { mic_len = tsch_security_mic_len(frame); if(buf_size < curr_len + mic_len) { return 0; } } #endif /* LLSEC802154_ENABLED */ /* Parse information elements. We need to substract the MIC length, as the exact payload len is needed while parsing */ if((ret = frame802154e_parse_information_elements(buf + curr_len, buf_size - curr_len - mic_len, ies)) == -1) { PRINTF("TSCH:! parse_eb: failed to parse IEs\n"); return 0; } curr_len += ret; } if(hdr_len != NULL) { *hdr_len += ies->ie_payload_ie_offset; } return curr_len; }
/* Parse enhanced ACK packet, extract drift and nack */ int tsch_packet_parse_eack(const uint8_t *buf, int buf_size, uint8_t seqno, frame802154_t *frame, struct ieee802154_ies *ies, uint8_t *hdr_len) { uint8_t curr_len = 0; int ret; linkaddr_t dest; if(frame == NULL || buf_size < 0) { return 0; } /* Parse 802.15.4-2006 frame, i.e. all fields before Information Elements */ if((ret = frame802154_parse((uint8_t *)buf, buf_size, frame)) < 3) { return 0; } if(hdr_len != NULL) { *hdr_len = ret; } curr_len += ret; /* Check seqno */ if(seqno != frame->seq) { return 0; } /* Check destination PAN ID */ if(frame802154_check_dest_panid(frame) == 0) { return 0; } /* Check destination address (if any) */ if(frame802154_extract_linkaddr(frame, NULL, &dest) == 0 || (!linkaddr_cmp(&dest, &linkaddr_node_addr) && !linkaddr_cmp(&dest, &linkaddr_null))) { return 0; } if(ies != NULL) { memset(ies, 0, sizeof(struct ieee802154_ies)); } if(frame->fcf.ie_list_present) { int mic_len = 0; #if LLSEC802154_ENABLED /* Check if there is space for the security MIC (if any) */ mic_len = tsch_security_mic_len(frame); if(buf_size < curr_len + mic_len) { return 0; } #endif /* LLSEC802154_ENABLED */ /* Parse information elements. We need to substract the MIC length, as the exact payload len is needed while parsing */ if((ret = frame802154e_parse_information_elements(buf + curr_len, buf_size - curr_len - mic_len, ies)) == -1) { return 0; } curr_len += ret; } if(hdr_len != NULL) { *hdr_len += ies->ie_payload_ie_offset; } return curr_len; }