static inline void ieee802154_acknowledge(struct net_if *iface, struct ieee802154_mpdu *mpdu) { struct net_pkt *pkt; struct net_buf *frag; if (!mpdu->mhr.fs->fc.ar) { return; } pkt = net_pkt_get_reserve_tx(IEEE802154_ACK_PKT_LENGTH, K_FOREVER); if (!pkt) { return; } frag = net_pkt_get_frag(pkt, K_FOREVER); net_pkt_frag_insert(pkt, frag); if (ieee802154_create_ack_frame(iface, pkt, mpdu->mhr.fs->sequence)) { const struct ieee802154_radio_api *radio = iface->dev->driver_api; net_buf_add(frag, IEEE802154_ACK_PKT_LENGTH); radio->tx(iface->dev, pkt, frag); } net_pkt_unref(pkt); return; }
/* Allocate and send data to USB Host */ static void send_data(u8_t *cfg, u8_t *data, size_t len) { struct net_pkt *pkt; struct net_buf *buf; pkt = net_pkt_get_reserve_rx(0, K_NO_WAIT); if (!pkt) { SYS_LOG_DBG("No pkt available"); return; } buf = net_pkt_get_frag(pkt, K_NO_WAIT); if (!buf) { SYS_LOG_DBG("No fragment available"); net_pkt_unref(pkt); return; } net_pkt_frag_insert(pkt, buf); SYS_LOG_DBG("queue pkt %p buf %p len %u", pkt, buf, len); /* Add configuration id */ memcpy(net_buf_add(buf, 2), cfg, 2); memcpy(net_buf_add(buf, len), data, len); /* simulate LQI */ net_buf_add(buf, 1); /* simulate FCS */ net_buf_add(buf, 2); k_fifo_put(&tx_queue, pkt); }
struct net_pkt *net_ipv4_create_raw(struct net_pkt *pkt, const struct in_addr *src, const struct in_addr *dst, struct net_if *iface, u8_t next_header) { struct net_buf *header; header = net_pkt_get_frag(pkt, K_FOREVER); net_pkt_frag_insert(pkt, header); NET_IPV4_HDR(pkt)->vhl = 0x45; NET_IPV4_HDR(pkt)->tos = 0x00; NET_IPV4_HDR(pkt)->proto = 0; NET_IPV4_HDR(pkt)->ttl = net_if_ipv4_get_ttl(iface); NET_IPV4_HDR(pkt)->offset[0] = NET_IPV4_HDR(pkt)->offset[1] = 0; NET_IPV4_HDR(pkt)->id[0] = NET_IPV4_HDR(pkt)->id[1] = 0; net_ipaddr_copy(&NET_IPV4_HDR(pkt)->dst, dst); net_ipaddr_copy(&NET_IPV4_HDR(pkt)->src, src); NET_IPV4_HDR(pkt)->proto = next_header; net_pkt_set_ip_hdr_len(pkt, sizeof(struct net_ipv4_hdr)); net_pkt_set_family(pkt, AF_INET); net_buf_add(header, sizeof(struct net_ipv4_hdr)); return pkt; }
static inline struct net_pkt *prepare_arp_request(struct net_if *iface, struct net_pkt *req, struct net_eth_addr *addr) { struct net_pkt *pkt; struct net_buf *frag; struct net_arp_hdr *hdr, *req_hdr; struct net_eth_hdr *eth, *eth_req; pkt = net_pkt_get_reserve_rx(sizeof(struct net_eth_hdr), K_FOREVER); if (!pkt) { goto fail; } frag = net_pkt_get_frag(pkt, K_FOREVER); if (!frag) { goto fail; } net_pkt_frag_add(pkt, frag); net_pkt_set_iface(pkt, iface); hdr = NET_ARP_HDR(pkt); eth = NET_ETH_HDR(pkt); req_hdr = NET_ARP_HDR(req); eth_req = NET_ETH_HDR(req); eth->type = htons(NET_ETH_PTYPE_ARP); memset(ð->dst.addr, 0xff, sizeof(struct net_eth_addr)); memcpy(ð->src.addr, addr, sizeof(struct net_eth_addr)); hdr->hwtype = htons(NET_ARP_HTYPE_ETH); hdr->protocol = htons(NET_ETH_PTYPE_IP); hdr->hwlen = sizeof(struct net_eth_addr); hdr->protolen = sizeof(struct in_addr); hdr->opcode = htons(NET_ARP_REQUEST); memset(&hdr->dst_hwaddr.addr, 0x00, sizeof(struct net_eth_addr)); memcpy(&hdr->src_hwaddr.addr, addr, sizeof(struct net_eth_addr)); net_ipaddr_copy(&hdr->src_ipaddr, &req_hdr->src_ipaddr); net_ipaddr_copy(&hdr->dst_ipaddr, &req_hdr->dst_ipaddr); net_buf_add(frag, sizeof(struct net_arp_hdr)); return pkt; fail: net_pkt_unref(pkt); return NULL; }
static bool send_ipv4_udp_msg(struct net_if *iface, struct in_addr *src, struct in_addr *dst, u16_t src_port, u16_t dst_port, struct ud *ud, bool expect_failure) { struct net_pkt *pkt; struct net_buf *frag; int ret; pkt = net_pkt_get_reserve_tx(0, K_FOREVER); frag = net_pkt_get_frag(pkt, K_FOREVER); net_pkt_frag_add(pkt, frag); net_pkt_set_iface(pkt, iface); net_pkt_set_ll_reserve(pkt, net_buf_headroom(frag)); setup_ipv4_udp(pkt, src, dst, src_port, dst_port); ret = net_recv_data(iface, pkt); if (ret < 0) { printk("Cannot recv pkt %p, ret %d\n", pkt, ret); zassert_true(0, "exiting"); } if (k_sem_take(&recv_lock, TIMEOUT)) { /**TESTPOINT: Check for failure*/ zassert_true(expect_failure, "Timeout, packet not received"); return true; } /* Check that the returned user data is the same as what was given * as a parameter. */ if (ud != returned_ud && !expect_failure) { printk("IPv4 wrong user data %p returned, expected %p\n", returned_ud, ud); zassert_true(0, "exiting"); } return !fail; }
static struct net_pkt *frame_get(struct gmac_queue *queue) { struct gmac_desc_list *rx_desc_list = &queue->rx_desc_list; struct gmac_desc *rx_desc; struct ring_buf *rx_frag_list = &queue->rx_frag_list; struct net_pkt *rx_frame; bool frame_is_complete; struct net_buf *frag; struct net_buf *new_frag; struct net_buf *last_frag = NULL; u8_t *frag_data; u32_t frag_len; u32_t frame_len = 0; u16_t tail; /* Check if there exists a complete frame in RX descriptor list */ tail = rx_desc_list->tail; rx_desc = &rx_desc_list->buf[tail]; frame_is_complete = false; while ((rx_desc->w0 & GMAC_RXW0_OWNERSHIP) && !frame_is_complete) { frame_is_complete = (bool)(rx_desc->w1 & GMAC_RXW1_EOF); MODULO_INC(tail, rx_desc_list->len); rx_desc = &rx_desc_list->buf[tail]; } /* Frame which is not complete can be dropped by GMAC. Do not process * it, even partially. */ if (!frame_is_complete) { return NULL; } rx_frame = net_pkt_get_reserve_rx(0, K_NO_WAIT); /* Process a frame */ tail = rx_desc_list->tail; rx_desc = &rx_desc_list->buf[tail]; frame_is_complete = false; /* TODO: Don't assume first RX fragment will have SOF (Start of frame) * bit set. If SOF bit is missing recover gracefully by dropping * invalid frame. */ __ASSERT(rx_desc->w1 & GMAC_RXW1_SOF, "First RX fragment is missing SOF bit"); /* TODO: We know already tail and head indexes of fragments containing * complete frame. Loop over those indexes, don't search for them * again. */ while ((rx_desc->w0 & GMAC_RXW0_OWNERSHIP) && !frame_is_complete) { frag = (struct net_buf *)rx_frag_list->buf[tail]; frag_data = (u8_t *)(rx_desc->w0 & GMAC_RXW0_ADDR); __ASSERT(frag->data == frag_data, "RX descriptor and buffer list desynchronized"); frame_is_complete = (bool)(rx_desc->w1 & GMAC_RXW1_EOF); if (frame_is_complete) { frag_len = (rx_desc->w1 & GMAC_TXW1_LEN) - frame_len; } else { frag_len = CONFIG_NET_BUF_DATA_SIZE; } frame_len += frag_len; /* Link frame fragments only if RX net buffer is valid */ if (rx_frame != NULL) { /* Assure cache coherency after DMA write operation */ DCACHE_INVALIDATE(frag_data, frag_len); /* Get a new data net buffer from the buffer pool */ new_frag = net_pkt_get_frag(rx_frame, K_NO_WAIT); if (new_frag == NULL) { queue->err_rx_frames_dropped++; net_pkt_unref(rx_frame); rx_frame = NULL; } else { net_buf_add(frag, frag_len); if (!last_frag) { net_pkt_frag_insert(rx_frame, frag); } else { net_buf_frag_insert(last_frag, frag); } last_frag = frag; frag = new_frag; rx_frag_list->buf[tail] = (u32_t)frag; } } /* Update buffer descriptor status word */ rx_desc->w1 = 0; /* Guarantee that status word is written before the address * word to avoid race condition. */ __DMB(); /* data memory barrier */ /* Update buffer descriptor address word */ rx_desc->w0 = ((u32_t)frag->data & GMAC_RXW0_ADDR) | (tail == rx_desc_list->len-1 ? GMAC_RXW0_WRAP : 0); MODULO_INC(tail, rx_desc_list->len); rx_desc = &rx_desc_list->buf[tail]; } rx_desc_list->tail = tail; SYS_LOG_DBG("Frame complete: rx=%p, tail=%d", rx_frame, tail); __ASSERT_NO_MSG(frame_is_complete); return rx_frame; }
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 bool run_tests(void) { struct net_pkt *pkt, *pkt2; struct net_buf *frag; struct net_if *iface; struct net_if_addr *ifaddr; struct net_arp_hdr *arp_hdr; struct net_ipv4_hdr *ipv4; struct net_eth_hdr *eth_hdr; int len; struct in_addr dst = { { { 192, 168, 0, 2 } } }; struct in_addr dst_far = { { { 10, 11, 12, 13 } } }; struct in_addr dst_far2 = { { { 172, 16, 14, 186 } } }; struct in_addr src = { { { 192, 168, 0, 1 } } }; struct in_addr netmask = { { { 255, 255, 255, 0 } } }; struct in_addr gw = { { { 192, 168, 0, 42 } } }; net_arp_init(); iface = net_if_get_default(); net_if_ipv4_set_gw(iface, &gw); net_if_ipv4_set_netmask(iface, &netmask); /* Unicast test */ ifaddr = net_if_ipv4_addr_add(iface, &src, NET_ADDR_MANUAL, 0); ifaddr->addr_state = NET_ADDR_PREFERRED; /* Application data for testing */ pkt = net_pkt_get_reserve_tx(sizeof(struct net_eth_hdr), K_FOREVER); if (!pkt) { printk("Out of mem TX\n"); return false; } frag = net_pkt_get_frag(pkt, K_FOREVER); if (!frag) { printk("Out of mem DATA\n"); return false; } net_pkt_frag_add(pkt, frag); net_pkt_set_iface(pkt, iface); setup_eth_header(iface, pkt, &hwaddr, NET_ETH_PTYPE_IP); len = strlen(app_data); if (net_pkt_ll_reserve(pkt) != sizeof(struct net_eth_hdr)) { printk("LL reserve invalid, should be %zd was %d\n", sizeof(struct net_eth_hdr), net_pkt_ll_reserve(pkt)); return false; } ipv4 = (struct net_ipv4_hdr *)net_buf_add(frag, sizeof(struct net_ipv4_hdr)); net_ipaddr_copy(&ipv4->src, &src); net_ipaddr_copy(&ipv4->dst, &dst); memcpy(net_buf_add(frag, len), app_data, len); pkt2 = net_arp_prepare(pkt); /* pkt2 is the ARP packet and pkt is the IPv4 packet and it was * stored in ARP table. */ if (pkt2 == pkt) { /* The packets cannot be the same as the ARP cache has * still room for the pkt. */ printk("ARP cache should still have free space\n"); return false; } if (!pkt2) { printk("ARP pkt is empty\n"); return false; } /* The ARP cache should now have a link to pending net_pkt * that is to be sent after we have got an ARP reply. */ if (!pkt->frags) { printk("Pending pkt fragment is NULL\n"); return false; } pending_pkt = pkt; /* pkt2 should contain the arp header, verify it */ if (memcmp(net_pkt_ll(pkt2), net_eth_broadcast_addr(), sizeof(struct net_eth_addr))) { printk("ARP ETH dest address invalid\n"); net_hexdump("ETH dest wrong ", net_pkt_ll(pkt2), sizeof(struct net_eth_addr)); net_hexdump("ETH dest correct", (u8_t *)net_eth_broadcast_addr(), sizeof(struct net_eth_addr)); return false; } if (memcmp(net_pkt_ll(pkt2) + sizeof(struct net_eth_addr), iface->link_addr.addr, sizeof(struct net_eth_addr))) { printk("ARP ETH source address invalid\n"); net_hexdump("ETH src correct", iface->link_addr.addr, sizeof(struct net_eth_addr)); net_hexdump("ETH src wrong ", net_pkt_ll(pkt2) + sizeof(struct net_eth_addr), sizeof(struct net_eth_addr)); return false; } arp_hdr = NET_ARP_HDR(pkt2); eth_hdr = NET_ETH_HDR(pkt2); if (eth_hdr->type != htons(NET_ETH_PTYPE_ARP)) { printk("ETH type 0x%x, should be 0x%x\n", eth_hdr->type, htons(NET_ETH_PTYPE_ARP)); return false; } if (arp_hdr->hwtype != htons(NET_ARP_HTYPE_ETH)) { printk("ARP hwtype 0x%x, should be 0x%x\n", arp_hdr->hwtype, htons(NET_ARP_HTYPE_ETH)); return false; } if (arp_hdr->protocol != htons(NET_ETH_PTYPE_IP)) { printk("ARP protocol 0x%x, should be 0x%x\n", arp_hdr->protocol, htons(NET_ETH_PTYPE_IP)); return false; } if (arp_hdr->hwlen != sizeof(struct net_eth_addr)) { printk("ARP hwlen 0x%x, should be 0x%zx\n", arp_hdr->hwlen, sizeof(struct net_eth_addr)); return false; } if (arp_hdr->protolen != sizeof(struct in_addr)) { printk("ARP IP addr len 0x%x, should be 0x%zx\n", arp_hdr->protolen, sizeof(struct in_addr)); return false; } if (arp_hdr->opcode != htons(NET_ARP_REQUEST)) { printk("ARP opcode 0x%x, should be 0x%x\n", arp_hdr->opcode, htons(NET_ARP_REQUEST)); return false; } if (!net_ipv4_addr_cmp(&arp_hdr->dst_ipaddr, &NET_IPV4_HDR(pkt)->dst)) { char out[sizeof("xxx.xxx.xxx.xxx")]; snprintk(out, sizeof(out), "%s", net_sprint_ipv4_addr(&arp_hdr->dst_ipaddr)); printk("ARP IP dest invalid %s, should be %s", out, net_sprint_ipv4_addr(&NET_IPV4_HDR(pkt)->dst)); return false; } if (!net_ipv4_addr_cmp(&arp_hdr->src_ipaddr, &NET_IPV4_HDR(pkt)->src)) { char out[sizeof("xxx.xxx.xxx.xxx")]; snprintk(out, sizeof(out), "%s", net_sprint_ipv4_addr(&arp_hdr->src_ipaddr)); printk("ARP IP src invalid %s, should be %s", out, net_sprint_ipv4_addr(&NET_IPV4_HDR(pkt)->src)); return false; } /* We could have send the new ARP request but for this test we * just free it. */ net_pkt_unref(pkt2); if (pkt->ref != 2) { printk("ARP cache should own the original packet\n"); return false; } /* Then a case where target is not in the same subnet */ net_ipaddr_copy(&ipv4->dst, &dst_far); pkt2 = net_arp_prepare(pkt); if (pkt2 == pkt) { printk("ARP cache should not find anything\n"); return false; } if (!pkt2) { printk("ARP pkt2 is empty\n"); return false; } arp_hdr = NET_ARP_HDR(pkt2); if (!net_ipv4_addr_cmp(&arp_hdr->dst_ipaddr, &iface->ipv4.gw)) { char out[sizeof("xxx.xxx.xxx.xxx")]; snprintk(out, sizeof(out), "%s", net_sprint_ipv4_addr(&arp_hdr->dst_ipaddr)); printk("ARP IP dst invalid %s, should be %s\n", out, net_sprint_ipv4_addr(&iface->ipv4.gw)); return false; } net_pkt_unref(pkt2); /* Try to find the same destination again, this should fail as there * is a pending request in ARP cache. */ net_ipaddr_copy(&ipv4->dst, &dst_far); /* Make sure prepare will not free the pkt because it will be * needed in the later test case. */ net_pkt_ref(pkt); pkt2 = net_arp_prepare(pkt); if (!pkt2) { printk("ARP cache is not sending the request again\n"); return false; } net_pkt_unref(pkt2); /* Try to find the different destination, this should fail too * as the cache table should be full. */ net_ipaddr_copy(&ipv4->dst, &dst_far2); /* Make sure prepare will not free the pkt because it will be * needed in the next test case. */ net_pkt_ref(pkt); pkt2 = net_arp_prepare(pkt); if (!pkt2) { printk("ARP cache did not send a req\n"); return false; } /* Restore the original address so that following test case can * work properly. */ net_ipaddr_copy(&ipv4->dst, &dst); /* The arp request packet is now verified, create an arp reply. * The previous value of pkt is stored in arp table and is not lost. */ pkt = net_pkt_get_reserve_rx(sizeof(struct net_eth_hdr), K_FOREVER); if (!pkt) { printk("Out of mem RX reply\n"); return false; } printk("%d pkt %p\n", __LINE__, pkt); frag = net_pkt_get_frag(pkt, K_FOREVER); if (!frag) { printk("Out of mem DATA reply\n"); return false; } printk("%d frag %p\n", __LINE__, frag); net_pkt_frag_add(pkt, frag); net_pkt_set_iface(pkt, iface); arp_hdr = NET_ARP_HDR(pkt); net_buf_add(frag, sizeof(struct net_arp_hdr)); net_ipaddr_copy(&arp_hdr->dst_ipaddr, &dst); net_ipaddr_copy(&arp_hdr->src_ipaddr, &src); pkt2 = prepare_arp_reply(iface, pkt, &hwaddr); if (!pkt2) { printk("ARP reply generation failed."); return false; } /* The pending packet should now be sent */ switch (net_arp_input(pkt2)) { case NET_OK: case NET_CONTINUE: break; case NET_DROP: break; } /* Yielding so that network interface TX thread can proceed. */ k_yield(); if (send_status < 0) { printk("ARP reply was not sent\n"); return false; } if (pkt->ref != 1) { printk("ARP cache should no longer own the original packet\n"); return false; } net_pkt_unref(pkt); /* Then feed in ARP request */ pkt = net_pkt_get_reserve_rx(sizeof(struct net_eth_hdr), K_FOREVER); if (!pkt) { printk("Out of mem RX request\n"); return false; } frag = net_pkt_get_frag(pkt, K_FOREVER); if (!frag) { printk("Out of mem DATA request\n"); return false; } net_pkt_frag_add(pkt, frag); net_pkt_set_iface(pkt, iface); send_status = -EINVAL; arp_hdr = NET_ARP_HDR(pkt); net_buf_add(frag, sizeof(struct net_arp_hdr)); net_ipaddr_copy(&arp_hdr->dst_ipaddr, &src); net_ipaddr_copy(&arp_hdr->src_ipaddr, &dst); setup_eth_header(iface, pkt, &hwaddr, NET_ETH_PTYPE_ARP); pkt2 = prepare_arp_request(iface, pkt, &hwaddr); if (!pkt2) { printk("ARP request generation failed."); return false; } req_test = true; switch (net_arp_input(pkt2)) { case NET_OK: case NET_CONTINUE: break; case NET_DROP: break; } /* Yielding so that network interface TX thread can proceed. */ k_yield(); if (send_status < 0) { printk("ARP req was not sent\n"); return false; } net_pkt_unref(pkt); printk("Network ARP checks passed\n"); return true; }
static inline int slip_input_byte(struct slip_context *slip, unsigned char c) { switch (slip->state) { case STATE_GARBAGE: if (c == SLIP_END) { slip->state = STATE_OK; } return 0; case STATE_ESC: if (c == SLIP_ESC_END) { c = SLIP_END; } else if (c == SLIP_ESC_ESC) { c = SLIP_ESC; } else { slip->state = STATE_GARBAGE; SLIP_STATS(slip->garbage++); return 0; } slip->state = STATE_OK; break; case STATE_OK: if (c == SLIP_ESC) { slip->state = STATE_ESC; return 0; } if (c == SLIP_END) { slip->state = STATE_OK; slip->first = false; if (slip->rx) { return 1; } return 0; } if (slip->first && !slip->rx) { /* Must have missed buffer allocation on first byte. */ return 0; } if (!slip->first) { slip->first = true; slip->rx = net_pkt_get_reserve_rx(0, K_NO_WAIT); if (!slip->rx) { SYS_LOG_ERR("[%p] cannot allocate pkt", slip); return 0; } slip->last = net_pkt_get_frag(slip->rx, K_NO_WAIT); if (!slip->last) { SYS_LOG_ERR("[%p] cannot allocate 1st data frag", slip); net_pkt_unref(slip->rx); slip->rx = NULL; return 0; } net_pkt_frag_add(slip->rx, slip->last); slip->ptr = net_pkt_ip_data(slip->rx); } break; } /* It is possible that slip->last is not set during the startup * of the device. If this happens do not continue and overwrite * some random memory. */ if (!slip->last) { return 0; } if (!net_buf_tailroom(slip->last)) { /* We need to allocate a new fragment */ struct net_buf *frag; frag = net_pkt_get_reserve_rx_data(0, K_NO_WAIT); if (!frag) { SYS_LOG_ERR("[%p] cannot allocate next data frag", slip); net_pkt_unref(slip->rx); slip->rx = NULL; slip->last = NULL; return 0; } net_buf_frag_insert(slip->last, frag); slip->last = frag; slip->ptr = slip->last->data; } /* The net_buf_add_u8() cannot add data to ll header so we need * a way to do it. */ if (slip->ptr < slip->last->data) { *slip->ptr = c; } else { slip->ptr = net_buf_add_u8(slip->last, c); } slip->ptr++; return 0; }
static int slip_process_byte(unsigned char c) { struct net_buf *buf; #ifdef VERBOSE_DEBUG SYS_LOG_DBG("recv: state %u byte %x", slip_state, c); #endif switch (slip_state) { case STATE_GARBAGE: if (c == SLIP_END) { slip_state = STATE_OK; } SYS_LOG_DBG("garbage: discard byte %x", c); return 0; case STATE_ESC: if (c == SLIP_ESC_END) { c = SLIP_END; } else if (c == SLIP_ESC_ESC) { c = SLIP_ESC; } else { slip_state = STATE_GARBAGE; return 0; } slip_state = STATE_OK; break; case STATE_OK: if (c == SLIP_ESC) { slip_state = STATE_ESC; return 0; } else if (c == SLIP_END) { return 1; } break; } #ifdef VERBOSE_DEBUG SYS_LOG_DBG("processed: state %u byte %x", slip_state, c); #endif if (!pkt_curr) { pkt_curr = net_pkt_get_reserve_rx(0, K_NO_WAIT); if (!pkt_curr) { SYS_LOG_ERR("No more buffers"); return 0; } buf = net_pkt_get_frag(pkt_curr, K_NO_WAIT); if (!buf) { SYS_LOG_ERR("No more buffers"); net_pkt_unref(pkt_curr); return 0; } net_pkt_frag_insert(pkt_curr, buf); } else { buf = net_buf_frag_last(pkt_curr->frags); } if (!net_buf_tailroom(buf)) { SYS_LOG_ERR("No more buf space: buf %p len %u", buf, buf->len); net_pkt_unref(pkt_curr); pkt_curr = NULL; return 0; } net_buf_add_u8(buf, c); return 0; }
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; }
struct net_pkt * ieee802154_create_mac_cmd_frame(struct ieee802154_context *ctx, enum ieee802154_cfi type, struct ieee802154_frame_params *params) { struct ieee802154_fcf_seq *fs; struct net_pkt *pkt; struct net_buf *frag; u8_t *p_buf; pkt = net_pkt_get_reserve_tx(0, K_FOREVER); if (!pkt) { return NULL; } frag = net_pkt_get_frag(pkt, K_FOREVER); if (!frag) { goto error; } net_pkt_frag_add(pkt, frag); p_buf = net_pkt_ll(pkt); fs = generate_fcf_grounds(&p_buf, type == IEEE802154_CFI_BEACON_REQUEST ? false : ctx->ack_requested); fs->fc.frame_type = IEEE802154_FRAME_TYPE_MAC_COMMAND; fs->sequence = ctx->sequence; if (!cfi_to_fs_settings(type, fs, params)) { goto error; } p_buf = generate_addressing_fields(ctx, fs, params, p_buf); /* Let's insert the cfi */ ((struct ieee802154_command *)p_buf)->cfi = type; /* In MAC command, we consider ll header being the mhr. * Rest will be the MAC command itself. This will proove * to be easy to handle afterwards to point directly to MAC * command space, in order to fill-in its content. */ net_pkt_set_ll_reserve(pkt, p_buf - net_pkt_ll(pkt)); net_buf_pull(frag, net_pkt_ll_reserve(pkt)); /* Thus setting the right MAC command length * Now up to the caller to fill-in this space relevantly. * See ieee802154_mac_command() helper. */ frag->len = mac_command_length(type); dbg_print_fs(fs); return pkt; error: net_pkt_unref(pkt); return NULL; }