Example #1
0
static void nrf5_rx_thread(void *arg1, void *arg2, void *arg3)
{
	struct device *dev = (struct device *)arg1;
	struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev);
	struct net_buf *frag = NULL;
	enum net_verdict ack_result;
	struct net_pkt *pkt;
	u8_t pkt_len;

	ARG_UNUSED(arg2);
	ARG_UNUSED(arg3);

	while (1) {
		pkt = NULL;

		SYS_LOG_DBG("Waiting for frame");
		k_sem_take(&nrf5_radio->rx_wait, K_FOREVER);

		SYS_LOG_DBG("Frame received");

		pkt = net_pkt_get_reserve_rx(0, K_NO_WAIT);
		if (!pkt) {
			SYS_LOG_ERR("No pkt available");
			goto out;
		}

#if defined(CONFIG_IEEE802154_NRF5_RAW)
		/**
		 * Reserve 1 byte for length
		 */
		net_pkt_set_ll_reserve(pkt, 1);
#endif

		frag = net_pkt_get_frag(pkt, K_NO_WAIT);
		if (!frag) {
			SYS_LOG_ERR("No frag available");
			goto out;
		}

		net_pkt_frag_insert(pkt, frag);

		/* rx_mpdu contains length, psdu, fcs|lqi
		 * The last 2 bytes contain LQI or FCS, depending if
		 * automatic CRC handling is enabled or not, respectively.
		 */
#if defined(CONFIG_IEEE802154_NRF5_RAW)
		pkt_len = nrf5_radio->rx_psdu[0];
#else
		pkt_len = nrf5_radio->rx_psdu[0] -  NRF5_FCS_LENGTH;
#endif

		/* Skip length (first byte) and copy the payload */
		memcpy(frag->data, nrf5_radio->rx_psdu + 1, pkt_len);
		net_buf_add(frag, pkt_len);

		nrf_drv_radio802154_buffer_free(nrf5_radio->rx_psdu);

		ack_result = ieee802154_radio_handle_ack(nrf5_radio->iface,
							 pkt);
		if (ack_result == NET_OK) {
			SYS_LOG_DBG("ACK packet handled");
			goto out;
		}

		SYS_LOG_DBG("Caught a packet (%u) (LQI: %u)",
			    pkt_len, nrf5_radio->lqi);

		if (net_recv_data(nrf5_radio->iface, pkt) < 0) {
			SYS_LOG_DBG("Packet dropped by NET stack");
			goto out;
		}

		net_analyze_stack("nRF5 rx stack",
				  (unsigned char *)nrf5_radio->rx_stack,
				  CONFIG_IEEE802154_NRF5_RX_STACK_SIZE);
		continue;

out:
		if (pkt) {
			net_pkt_unref(pkt);
		}
	}
}
static u8_t *upipe_rx(u8_t *buf, size_t *off)
{
	struct net_pkt *pkt = NULL;
	struct upipe_context *upipe;

	if (!upipe_dev) {
		goto done;
	}

	upipe = upipe_dev->driver_data;
	if (!upipe->rx && *buf == UART_PIPE_RADIO_15_4_FRAME_TYPE) {
		upipe->rx = true;
		goto done;
	}

	if (!upipe->rx_len) {
		if (*buf > 127) {
			goto flush;
		}

		upipe->rx_len = *buf;
		goto done;
	}

	upipe->rx_buf[upipe->rx_off++] = *buf;

	if (upipe->rx_len == upipe->rx_off) {
		struct net_buf *frag;

		pkt = net_pkt_get_reserve_rx(K_NO_WAIT);
		if (!pkt) {
			LOG_DBG("No pkt available");
			goto flush;
		}

		frag = net_pkt_get_frag(pkt, K_NO_WAIT);
		if (!frag) {
			LOG_DBG("No fragment available");
			goto out;
		}

		net_pkt_frag_insert(pkt, frag);

		memcpy(frag->data, upipe->rx_buf, upipe->rx_len);
		net_buf_add(frag, upipe->rx_len);

#if defined(CONFIG_IEEE802154_UPIPE_HW_FILTER)
		if (received_dest_addr_matched(frag->data) == false) {
			LOG_DBG("Packet received is not addressed to me");
			goto out;
		}
#endif

		if (ieee802154_radio_handle_ack(upipe->iface, pkt) == NET_OK) {
			LOG_DBG("ACK packet handled");
			goto out;
		}

		LOG_DBG("Caught a packet (%u)", upipe->rx_len);
		if (net_recv_data(upipe->iface, pkt) < 0) {
			LOG_DBG("Packet dropped by NET stack");
			goto out;
		}

		goto flush;
out:
		net_pkt_unref(pkt);
flush:
		upipe->rx = false;
		upipe->rx_len = 0U;
		upipe->rx_off = 0U;
	}
done:
	*off = 0;

	return buf;
}