diff --git a/drivers/at86rf2xx/at86rf2xx_netdev.c b/drivers/at86rf2xx/at86rf2xx_netdev.c index 24a959227b4e..b9158e11ea8d 100644 --- a/drivers/at86rf2xx/at86rf2xx_netdev.c +++ b/drivers/at86rf2xx/at86rf2xx_netdev.c @@ -132,6 +132,7 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) at86rf2xx_t *dev = (at86rf2xx_t *)netdev; uint8_t phr; size_t pkt_len; + uint16_t fcs; /* frame buffer protection will be unlocked as soon as at86rf2xx_fb_stop() * is called*/ @@ -159,25 +160,32 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) #endif /* copy payload */ at86rf2xx_fb_read(dev, (uint8_t *)buf, pkt_len); - - /* Ignore FCS but advance fb read - we must give a temporary buffer here, - * as we are not allowed to issue SPI transfers without any buffer */ - uint8_t tmp[2]; - at86rf2xx_fb_read(dev, tmp, 2); - (void)tmp; + /* copy fcs */ + at86rf2xx_fb_read(dev, (uint8_t *)&fcs, sizeof(uint16_t)); if (info != NULL) { uint8_t rssi = 0; + int8_t crc_ok = -1; netdev_ieee802154_rx_info_t *radio_info = info; at86rf2xx_fb_read(dev, &(radio_info->lqi), 1); #ifndef MODULE_AT86RF231 at86rf2xx_fb_read(dev, &(rssi), 1); + uint8_t rx_status = 0xFF; + at86rf2xx_fb_read(dev, &(rx_status), 1); + if((rx_status & 0xF) == 0) { + crc_ok = (rx_status & AT86RF2XX_PHY_RSSI_MASK__RX_CRC_VALID) ? 1 : 0; + } at86rf2xx_fb_stop(dev); #else at86rf2xx_fb_stop(dev); rssi = at86rf2xx_reg_read(dev, AT86RF2XX_REG__PHY_ED_LEVEL); + crc_ok = at86rf2xx_reg_read(dev, AT86RF2XX_REG__PHY_RSSI) & AT86RF2XX_PHY_RSSI_MASK__RX_CRC_VALID ? 1 : 0; + rssi &= AT86RF2XX_PHY_RSSI_MASK__RSSI; #endif radio_info->rssi = RSSI_BASE_VAL + rssi; + radio_info->crc_ok = crc_ok; + radio_info->fcs = fcs; + (void)crc_ok; } else { at86rf2xx_fb_stop(dev); diff --git a/drivers/cc2420/cc2420.c b/drivers/cc2420/cc2420.c index 24c159255ab4..cd2a9dbca75e 100644 --- a/drivers/cc2420/cc2420.c +++ b/drivers/cc2420/cc2420.c @@ -200,6 +200,7 @@ int cc2420_rx(cc2420_t *dev, uint8_t *buf, size_t max_len, void *info) netdev_ieee802154_rx_info_t *radio_info = info; radio_info->rssi = CC2420_RSSI_OFFSET + rssi; radio_info->lqi = crc_corr & CC2420_CRCCOR_COR_MASK; + radio_info->crc_ok = (uint16_t) ((crc_corr & ~CC2420_CRCCOR_COR_MASK)>>7); } /* finally flush the FIFO */ diff --git a/drivers/include/net/netdev.h b/drivers/include/net/netdev.h index e5424bb3f454..08e1035edd13 100644 --- a/drivers/include/net/netdev.h +++ b/drivers/include/net/netdev.h @@ -249,6 +249,8 @@ typedef enum { struct netdev_radio_rx_info { int16_t rssi; /**< RSSI of a received packet in dBm */ uint8_t lqi; /**< LQI of a received packet */ + uint16_t crc_ok; /**< CRC Ok of received packet */ + uint16_t fcs; /**< FCS of received packet */ }; /** diff --git a/sys/include/net/gnrc/netif/hdr.h b/sys/include/net/gnrc/netif/hdr.h index 3e6aef7eaa53..5f2c9df9f4ce 100644 --- a/sys/include/net/gnrc/netif/hdr.h +++ b/sys/include/net/gnrc/netif/hdr.h @@ -87,6 +87,8 @@ typedef struct { uint8_t flags; /**< flags as defined above */ uint8_t lqi; /**< lqi of received packet (optional) */ int16_t rssi; /**< rssi of received packet in dBm (optional) */ + uint8_t crc_ok; /**< crc valid indicator (optional) */ + uint16_t fcs; /**< FCS of received packet */ } gnrc_netif_hdr_t; /** diff --git a/sys/net/gnrc/link_layer/lwmac/lwmac.c b/sys/net/gnrc/link_layer/lwmac/lwmac.c index 402e20779955..647c5a42faa4 100644 --- a/sys/net/gnrc/link_layer/lwmac/lwmac.c +++ b/sys/net/gnrc/link_layer/lwmac/lwmac.c @@ -173,6 +173,8 @@ static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif) hdr->lqi = rx_info.lqi; hdr->rssi = rx_info.rssi; + hdr->crc_ok = rx_info.crc_ok; + hdr->fcs = rx_info.fcs; hdr->if_pid = thread_getpid(); pkt->type = state->proto; #if ENABLE_DEBUG diff --git a/sys/net/gnrc/netif/gnrc_netif_ieee802154.c b/sys/net/gnrc/netif/gnrc_netif_ieee802154.c index cb9c629d6c22..f3a8b9c66277 100644 --- a/sys/net/gnrc/netif/gnrc_netif_ieee802154.c +++ b/sys/net/gnrc/netif/gnrc_netif_ieee802154.c @@ -139,6 +139,8 @@ static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif) hdr->lqi = rx_info.lqi; hdr->rssi = rx_info.rssi; + hdr->crc_ok = rx_info.crc_ok; + hdr->fcs = rx_info.fcs; hdr->if_pid = thread_getpid(); pkt->type = state->proto; #if ENABLE_DEBUG diff --git a/sys/net/gnrc/netif/hdr/gnrc_netif_hdr_print.c b/sys/net/gnrc/netif/hdr/gnrc_netif_hdr_print.c index 275ea31705bf..d332025dbf38 100644 --- a/sys/net/gnrc/netif/hdr/gnrc_netif_hdr_print.c +++ b/sys/net/gnrc/netif/hdr/gnrc_netif_hdr_print.c @@ -24,7 +24,9 @@ void gnrc_netif_hdr_print(gnrc_netif_hdr_t *hdr) printf("if_pid: %u ", (unsigned) hdr->if_pid); printf("rssi: %d ", (signed) hdr->rssi); - printf("lqi: %u\n", (unsigned) hdr->lqi); + printf("lqi: %u ", (unsigned) hdr->lqi); + printf("crc_ok: %u ", (unsigned) hdr->crc_ok); + printf("fcs: %04x\n", (unsigned) hdr->fcs); printf("flags: "); if (hdr->flags) {