static void test_pktbuf_get_iovec__null(void) { gnrc_pktsnip_t *res; size_t len; res = gnrc_pktbuf_get_iovec(NULL, &len); TEST_ASSERT(res == NULL); TEST_ASSERT_EQUAL_INT(0, len); }
static void test_pktbuf_get_iovec__1_elem(void) { struct iovec *vec; size_t len; gnrc_pktsnip_t *snip = gnrc_pktbuf_add(NULL, TEST_STRING16, sizeof(TEST_STRING16), GNRC_NETTYPE_UNDEF); snip = gnrc_pktbuf_get_iovec(snip, &len); vec = (struct iovec *)snip->data; TEST_ASSERT_EQUAL_INT(sizeof(struct iovec), snip->size); TEST_ASSERT_EQUAL_INT(1, len); TEST_ASSERT(snip->next->data == vec[0].iov_base); TEST_ASSERT_EQUAL_INT(snip->next->size, vec[0].iov_len); gnrc_pktbuf_release(snip); TEST_ASSERT(gnrc_pktbuf_is_empty()); }
static int _send(gnrc_netdev2_t *gnrc_netdev2, gnrc_pktsnip_t *pkt) { ethernet_hdr_t hdr; gnrc_netif_hdr_t *netif_hdr; gnrc_pktsnip_t *payload; netdev2_t *dev = gnrc_netdev2->dev; if (pkt == NULL) { DEBUG("gnrc_netdev2_eth: pkt was NULL"); return -EINVAL; } payload = pkt->next; if (pkt->type != GNRC_NETTYPE_NETIF) { DEBUG("gnrc_netdev2_eth: First header was not generic netif header\n"); return -EBADMSG; } if (payload) { hdr.type = byteorder_htons(gnrc_nettype_to_ethertype(payload->type)); } else { hdr.type = byteorder_htons(ETHERTYPE_UNKNOWN); } netif_hdr = pkt->data; /* set ethernet header */ if (netif_hdr->src_l2addr_len == ETHERNET_ADDR_LEN) { memcpy(hdr.dst, gnrc_netif_hdr_get_src_addr(netif_hdr), netif_hdr->src_l2addr_len); } else { dev->driver->get(dev, NETOPT_ADDRESS, hdr.src, ETHERNET_ADDR_LEN); } if (netif_hdr->flags & GNRC_NETIF_HDR_FLAGS_BROADCAST) { _addr_set_broadcast(hdr.dst); } else if (netif_hdr->flags & GNRC_NETIF_HDR_FLAGS_MULTICAST) { _addr_set_multicast(hdr.dst, payload); } else if (netif_hdr->dst_l2addr_len == ETHERNET_ADDR_LEN) { memcpy(hdr.dst, gnrc_netif_hdr_get_dst_addr(netif_hdr), ETHERNET_ADDR_LEN); } else { DEBUG("gnrc_netdev2_eth: destination address had unexpected format\n"); return -EBADMSG; } DEBUG("gnrc_netdev2_eth: send to %02x:%02x:%02x:%02x:%02x:%02x\n", hdr.dst[0], hdr.dst[1], hdr.dst[2], hdr.dst[3], hdr.dst[4], hdr.dst[5]); size_t n; pkt = gnrc_pktbuf_get_iovec(pkt, &n); struct iovec *vector = (struct iovec *)pkt->data; vector[0].iov_base = (char*)&hdr; vector[0].iov_len = sizeof(ethernet_hdr_t); dev->driver->send(dev, vector, n); gnrc_pktbuf_release(pkt); return 0; }
static int _send(gnrc_netdev2_t *gnrc_netdev2, gnrc_pktsnip_t *pkt) { netdev2_t *netdev = gnrc_netdev2->dev; netdev2_ieee802154_t *state = (netdev2_ieee802154_t *)gnrc_netdev2->dev; gnrc_netif_hdr_t *netif_hdr; gnrc_pktsnip_t *vec_snip; uint8_t *src, *dst = NULL; int res = 0; size_t n, src_len; uint8_t mhr[IEEE802154_MAX_HDR_LEN]; uint8_t flags = (uint8_t)(state->flags & NETDEV2_IEEE802154_SEND_MASK); le_uint16_t dev_pan = byteorder_btols(byteorder_htons(state->pan)); flags |= IEEE802154_FCF_TYPE_DATA; if (pkt == NULL) { DEBUG("_send_ieee802154: pkt was NULL\n"); return -EINVAL; } if (pkt->type != GNRC_NETTYPE_NETIF) { DEBUG("_send_ieee802154: first header is not generic netif header\n"); return -EBADMSG; } netif_hdr = pkt->data; /* prepare destination address */ if (netif_hdr->flags & /* If any of these flags is set so this is correct */ (GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) { flags |= IEEE802154_BCAST; } else { dst = gnrc_netif_hdr_get_dst_addr(netif_hdr); } src_len = netif_hdr->src_l2addr_len; if (src_len > 0) { src = gnrc_netif_hdr_get_src_addr(netif_hdr); } else if (state->flags & NETDEV2_IEEE802154_SRC_MODE_LONG) { src_len = IEEE802154_LONG_ADDRESS_LEN; src = state->long_addr; } else { src_len = IEEE802154_SHORT_ADDRESS_LEN; src = state->short_addr; } /* fill MAC header, seq should be set by device */ if ((res = ieee802154_set_frame_hdr(mhr, src, src_len, dst, netif_hdr->dst_l2addr_len, dev_pan, dev_pan, flags, state->seq++)) == 0) { DEBUG("_send_ieee802154: Error preperaring frame\n"); return -EINVAL; } /* prepare packet for sending */ vec_snip = gnrc_pktbuf_get_iovec(pkt, &n); if (vec_snip != NULL) { struct iovec *vector; pkt = vec_snip; /* reassign for later release; vec_snip is prepended to pkt */ vector = (struct iovec *)pkt->data; vector[0].iov_base = mhr; vector[0].iov_len = (size_t)res; res = netdev->driver->send(netdev, vector, n); } else { return -ENOBUFS; } /* release old data */ gnrc_pktbuf_release(pkt); return res; }
int _gnrc_gomach_transmit(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) { netdev_t *dev = netif->dev; netdev_ieee802154_t *state = (netdev_ieee802154_t *)netif->dev; gnrc_netif_hdr_t *netif_hdr; gnrc_pktsnip_t *vec_snip; const uint8_t *src, *dst = NULL; int res = 0; size_t n, src_len, dst_len; uint8_t mhr[IEEE802154_MAX_HDR_LEN]; uint8_t flags = (uint8_t)(state->flags & NETDEV_IEEE802154_SEND_MASK); le_uint16_t dev_pan = byteorder_btols(byteorder_htons(state->pan)); flags |= IEEE802154_FCF_TYPE_DATA; if (pkt == NULL) { DEBUG("_send_ieee802154: pkt was NULL\n"); return -EINVAL; } if (pkt->type != GNRC_NETTYPE_NETIF) { DEBUG("_send_ieee802154: first header is not generic netif header\n"); return -EBADMSG; } netif_hdr = pkt->data; /* prepare destination address */ if (netif_hdr->flags & /* If any of these flags is set assume broadcast */ (GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) { dst = ieee802154_addr_bcast; dst_len = IEEE802154_ADDR_BCAST_LEN; } else { dst = gnrc_netif_hdr_get_dst_addr(netif_hdr); dst_len = netif_hdr->dst_l2addr_len; } src_len = netif_hdr->src_l2addr_len; if (src_len > 0) { src = gnrc_netif_hdr_get_src_addr(netif_hdr); } else { src_len = netif->l2addr_len; src = netif->l2addr; } /* fill MAC header, seq should be set by device */ if ((res = ieee802154_set_frame_hdr(mhr, src, src_len, dst, dst_len, dev_pan, dev_pan, flags, state->seq++)) == 0) { DEBUG("_send_ieee802154: Error preperaring frame\n"); return -EINVAL; } /* prepare packet for sending */ vec_snip = gnrc_pktbuf_get_iovec(pkt, &n); if (vec_snip != NULL) { struct iovec *vector; pkt = vec_snip; /* reassign for later release; vec_snip is prepended to pkt */ vector = (struct iovec *)pkt->data; vector[0].iov_base = mhr; vector[0].iov_len = (size_t)res; #ifdef MODULE_NETSTATS_L2 if (netif_hdr->flags & (GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) { netif->dev->stats.tx_mcast_count++; } else { netif->dev->stats.tx_unicast_count++; } #endif #ifdef MODULE_GNRC_MAC if (netif->mac.mac_info & GNRC_NETIF_MAC_INFO_CSMA_ENABLED) { res = csma_sender_csma_ca_send(dev, vector, n, &netif->mac.csma_conf); } else { res = dev->driver->send(dev, vector, n); } #else res = dev->driver->send(dev, vector, n); #endif } else { return -ENOBUFS; } /* release old data */ gnrc_pktbuf_release(pkt); return res; }