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; }