gnrc_pktsnip_t *gnrc_netif_hdr_build(const uint8_t *src, uint8_t src_len, const uint8_t *dst, uint8_t dst_len) { gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, NULL, sizeof(gnrc_netif_hdr_t) + src_len + dst_len, GNRC_NETTYPE_NETIF); if (pkt == NULL) { return NULL; } gnrc_netif_hdr_init(pkt->data, src_len, dst_len); if (src != NULL && src_len > 0) { gnrc_netif_hdr_set_src_addr(pkt->data, src, src_len); } if (dst != NULL && dst_len > 0) { gnrc_netif_hdr_set_dst_addr(pkt->data, dst, dst_len); } return pkt; }
static gnrc_pktsnip_t *_recv(gnrc_netdev2_t *gnrc_netdev2) { netdev2_t *dev = gnrc_netdev2->dev; cc110x_t *cc110x = &((netdev2_cc110x_t*) dev)->cc110x; cc110x_pkt_t *cc110x_pkt = &cc110x->pkt_buf.packet; int payload_length = cc110x_pkt->length - CC110X_HEADER_LENGTH; int nettype; int addr_len; switch (cc110x_pkt->flags) { #ifdef MODULE_GNRC_SIXLOWPAN case 1: addr_len = 8; nettype = GNRC_NETTYPE_SIXLOWPAN; break; #endif default: addr_len = 1; nettype = GNRC_NETTYPE_UNDEF; } /* copy packet payload into pktbuf */ gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, cc110x_pkt->data, payload_length, nettype); if(!pkt) { DEBUG("cc110x: _recv: cannot allocate pktsnip.\n"); return NULL; } gnrc_pktsnip_t *netif_hdr; netif_hdr = gnrc_pktbuf_add(NULL, NULL, sizeof(gnrc_netif_hdr_t) + 2*addr_len, GNRC_NETTYPE_NETIF); if (netif_hdr == NULL) { DEBUG("gnrc_netdev2_cc110x: no space left in packet buffer\n"); gnrc_pktbuf_release(pkt); return NULL; } gnrc_netif_hdr_init(netif_hdr->data, addr_len, addr_len); if (addr_len == 8) { uint64_t src_addr = cc110x_pkt->phy_src; uint64_t dst_addr = cc110x_pkt->address; gnrc_netif_hdr_set_src_addr(netif_hdr->data, (uint8_t*)&src_addr, addr_len); gnrc_netif_hdr_set_dst_addr(netif_hdr->data, (uint8_t*)&dst_addr, addr_len); } else { gnrc_netif_hdr_set_src_addr(netif_hdr->data, (uint8_t*)&cc110x_pkt->phy_src, addr_len); gnrc_netif_hdr_set_dst_addr(netif_hdr->data, (uint8_t*)&cc110x_pkt->address, addr_len); } ((gnrc_netif_hdr_t *)netif_hdr->data)->if_pid = thread_getpid(); ((gnrc_netif_hdr_t *)netif_hdr->data)->lqi = cc110x->pkt_buf.lqi; ((gnrc_netif_hdr_t *)netif_hdr->data)->rssi = cc110x->pkt_buf.rssi; DEBUG("gnrc_netdev2_cc110x: received packet from %02x" " of length %u\n", (unsigned)cc110x_pkt->phy_src, (unsigned)cc110x_pkt->length-CC110X_HEADER_LENGTH); #if defined(MODULE_OD) && ENABLE_DEBUG od_hex_dump(cc110x_pkt->data, payload_length, OD_WIDTH_DEFAULT); #endif pkt->next = netif_hdr; return pkt; }
static gnrc_pktsnip_t *_recv(gnrc_netdev2_t *gnrc_netdev2) { netdev2_t *dev = gnrc_netdev2->dev; int bytes_expected = dev->driver->recv(dev, NULL, 0); gnrc_pktsnip_t *pkt = NULL; if (bytes_expected) { pkt = gnrc_pktbuf_add(NULL, NULL, bytes_expected, GNRC_NETTYPE_UNDEF); if(!pkt) { DEBUG("_recv_ethernet_packet: cannot allocate pktsnip.\n"); goto out; } int nread = dev->driver->recv(dev, pkt->data, bytes_expected); if(nread <= 0) { DEBUG("_recv_ethernet_packet: read error.\n"); goto safe_out; } if (nread < bytes_expected) { /* we've got less then the expected packet size, * so free the unused space.*/ DEBUG("_recv_ethernet_packet: reallocating.\n"); gnrc_pktbuf_realloc_data(pkt, nread); } /* mark ethernet header */ gnrc_pktsnip_t *eth_hdr = gnrc_pktbuf_mark(pkt, sizeof(ethernet_hdr_t), GNRC_NETTYPE_UNDEF); if (!eth_hdr) { DEBUG("gnrc_netdev2_eth: no space left in packet buffer\n"); goto safe_out; } ethernet_hdr_t *hdr = (ethernet_hdr_t *)eth_hdr->data; /* set payload type from ethertype */ pkt->type = gnrc_nettype_from_ethertype(byteorder_ntohs(hdr->type)); /* create netif header */ gnrc_pktsnip_t *netif_hdr; netif_hdr = gnrc_pktbuf_add(NULL, NULL, sizeof(gnrc_netif_hdr_t) + (2 * ETHERNET_ADDR_LEN), GNRC_NETTYPE_NETIF); if (netif_hdr == NULL) { DEBUG("gnrc_netdev2_eth: no space left in packet buffer\n"); pkt = eth_hdr; goto safe_out; } gnrc_netif_hdr_init(netif_hdr->data, ETHERNET_ADDR_LEN, ETHERNET_ADDR_LEN); gnrc_netif_hdr_set_src_addr(netif_hdr->data, hdr->src, ETHERNET_ADDR_LEN); gnrc_netif_hdr_set_dst_addr(netif_hdr->data, hdr->dst, ETHERNET_ADDR_LEN); ((gnrc_netif_hdr_t *)netif_hdr->data)->if_pid = thread_getpid(); DEBUG("gnrc_netdev2_eth: received packet from %02x:%02x:%02x:%02x:%02x:%02x " "of length %zu\n", hdr->src[0], hdr->src[1], hdr->src[2], hdr->src[3], hdr->src[4], hdr->src[5], nread); #if defined(MODULE_OD) && ENABLE_DEBUG od_hex_dump(hdr, nread, OD_WIDTH_DEFAULT); #endif gnrc_pktbuf_remove_snip(pkt, eth_hdr); LL_APPEND(pkt, netif_hdr); } out: return pkt; safe_out: gnrc_pktbuf_release(pkt); return NULL; }