static int mac802154_header_create(struct sk_buff *skb, struct net_device *dev, unsigned short type, const void *daddr, const void *saddr, unsigned len) { struct ieee802154_hdr hdr; struct mac802154_sub_if_data *priv = netdev_priv(dev); struct ieee802154_mac_cb *cb = mac_cb(skb); int hlen; if (!daddr) return -EINVAL; memset(&hdr.fc, 0, sizeof(hdr.fc)); hdr.fc.type = cb->type; hdr.fc.security_enabled = cb->secen; hdr.fc.ack_request = cb->ackreq; hdr.seq = ieee802154_mlme_ops(dev)->get_dsn(dev); if (mac802154_set_header_security(priv, &hdr, cb) < 0) return -EINVAL; if (!saddr) { spin_lock_bh(&priv->mib_lock); if (priv->short_addr == cpu_to_le16(IEEE802154_ADDR_BROADCAST) || priv->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF) || priv->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST)) { hdr.source.mode = IEEE802154_ADDR_LONG; hdr.source.extended_addr = priv->extended_addr; } else { hdr.source.mode = IEEE802154_ADDR_SHORT; hdr.source.short_addr = priv->short_addr; } hdr.source.pan_id = priv->pan_id; spin_unlock_bh(&priv->mib_lock); } else { hdr.source = *(const struct ieee802154_addr *)saddr; } hdr.dest = *(const struct ieee802154_addr *)daddr; hlen = ieee802154_hdr_push(skb, &hdr); if (hlen < 0) return -EINVAL; skb_reset_mac_header(skb); skb->mac_len = hlen; if (len > ieee802154_max_payload(&hdr)) return -EMSGSIZE; return hlen; }
/* * Create the skb for the upper layer */ void xbee_rx(struct net_device *dev, unsigned char *data, int len, unsigned char* addr) { struct xbee_priv *priv = netdev_priv(dev); struct sk_buff *skb; struct ieee802154_mac_cb* cb; struct ieee802154_hdr hdr; int hlen; int packet_stat; memset(&hdr.fc, 0, sizeof(hdr.fc)); skb = dev_alloc_skb(len+sizeof(struct ieee802154_hdr)); if (!skb) { if (printk_ratelimit()) printk(KERN_NOTICE "[NET] xbee rx: low on mem - packet dropped\n"); priv->stats.rx_dropped++; return; } skb_reserve(skb, len); skb->dev = dev; //skb->pkt_type = PACKET_HOST; skb->protocol = htons(ETH_P_IEEE802154); cb = mac_cb(skb); hdr.source.mode = IEEE802154_ADDR_LONG; hdr.source.extended_addr = be64_to_cpup((__be64*)addr); hdr.source.pan_id = xbee_get_pan_id(dev); //cb->source.mode = IEEE802154_ADDR_LONG; //cb->source.pan_id = xbee_get_pan_id(dev); //cb->source.extended_addr = be64_to_cpup((__be64*)addr); hdr.dest.mode = IEEE802154_ADDR_LONG; hdr.dest.extended_addr = IEEE802154_ADDR_BROADCAST; hdr.dest.pan_id = xbee_get_pan_id(dev); hlen = ieee802154_hdr_push(skb, &hdr); if (hlen < 0) return ; skb->mac_len = hlen; skb_reset_mac_header(skb); if (len > ieee802154_max_payload(&hdr)) return ; // Put all the data into the socket buffer memcpy(skb_push(skb, len), data, len); skb->ip_summed = CHECKSUM_UNNECESSARY; // don't check it (does this make any difference?) skb->len = len; packet_stat = netif_rx(skb); if(packet_stat == NET_RX_SUCCESS) { printk(KERN_ALERT "[NET] Packet received successfully\n"); } else if(packet_stat == NET_RX_DROP) { printk(KERN_ALERT "[NET] Packet was dropped!\n"); } printk(KERN_ALERT "MAC SRC addr %llx\n", hdr.source.extended_addr); dev->stats.rx_packets++; dev->stats.rx_bytes += skb->len; }