diff --git a/drivers/mrf24j40/mrf24j40_netdev.c b/drivers/mrf24j40/mrf24j40_netdev.c index 10f534689b771cf128a4e8ac4be617b47efc0294..41c35395eff7333f5ef7f4eab2159cd414eb6029 100644 --- a/drivers/mrf24j40/mrf24j40_netdev.c +++ b/drivers/mrf24j40/mrf24j40_netdev.c @@ -110,46 +110,45 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) mrf24j40_t *dev = (mrf24j40_t *)netdev; uint8_t phr; size_t pkt_len; + int res = -ENOBUFS; /* Disable receiving while reading the RX fifo (datasheet sec. 3.11.4) */ mrf24j40_reg_write_short(dev, MRF24J40_REG_BBREG1, MRF24J40_BBREG1_RXDECINV ); - /* get the size of the received packet */ + /* get the size of the received packet, this resets the receive FIFO to be + * ready for a new frame, so we have to disable RX first (see above) */ phr = mrf24j40_reg_read_long(dev, MRF24J40_RX_FIFO); pkt_len = (phr & 0x7f) - 2; /* just return length when buf == NULL */ - if (buf == NULL) { + if (buf == NULL && len == 0) { return pkt_len; } + /* Only fill buffer if it is supplied and is large enough */ + if (buf && pkt_len <= len) { + /* copy payload */ + mrf24j40_rx_fifo_read(dev, 1, (uint8_t *)buf, pkt_len); + + if (info != NULL) { + netdev_ieee802154_rx_info_t *radio_info = info; + uint8_t rssi_scalar = 0; + /* Read LQI and RSSI values from the RX fifo */ + mrf24j40_rx_fifo_read(dev, phr + 1, &(radio_info->lqi), 1); + mrf24j40_rx_fifo_read(dev, phr + 2, &(rssi_scalar), 1); + radio_info->rssi = mrf24j40_dbm_from_reg(rssi_scalar); + } #ifdef MODULE_NETSTATS_L2 - netdev->stats.rx_count++; - netdev->stats.rx_bytes += pkt_len; + netdev->stats.rx_count++; + netdev->stats.rx_bytes += pkt_len; #endif - /* not enough space in buf */ - if (pkt_len > len) { - DEBUG("[mrf24j40] No space in receive buffers\n"); - mrf24j40_reg_write_short(dev, MRF24J40_REG_RXFLUSH, MRF24J40_RXFLUSH_RXFLUSH); - /* Turn on reception of packets off the air */ - mrf24j40_reg_write_short(dev, MRF24J40_REG_BBREG1, 0x00); - return -ENOBUFS; - } - /* copy payload */ - mrf24j40_rx_fifo_read(dev, 1, (uint8_t *)buf, pkt_len); - - if (info != NULL) { - netdev_ieee802154_rx_info_t *radio_info = info; - uint8_t rssi_scalar = 0; - /* Read LQI and RSSI values from the RX fifo */ - mrf24j40_rx_fifo_read(dev, phr + 1, &(radio_info->lqi), 1); - mrf24j40_rx_fifo_read(dev, phr + 2, &(rssi_scalar), 1); - radio_info->rssi = mrf24j40_dbm_from_reg(rssi_scalar); + res = pkt_len; } - /* Turn on reception of packets off the air */ mrf24j40_reg_write_short(dev, MRF24J40_REG_BBREG1, 0x00); - return pkt_len; + /* Return -ENOBUFS if a too small buffer is supplied. Return packet size + * otherwise */ + return res; } static netopt_state_t _get_state(mrf24j40_t *dev)