subsys/net/ip/l2/ieee802154/ieee802154_fragment.c
/**
 *  Parse size and tag from the fragment, check if we have any cache
 *  related to it. If not create a new cache.
 *  Remove the fragmentation header and uncompress IPv6 and related headers.
 *  Cache Rx part of fragment along with data buf for the first fragment
 *  in the cache, remaining fragments just cache data fragment, unref
 *  RX pkt. So in both the cases caller can assume packet is consumed.
 */
Parse size and tag from the fragment, check if we have any cache
related to it. If not create a new cache.
Remove the fragmentation header and uncompress IPv6 and related headers.
Cache Rx part of fragment along with data buf for the first fragment
in the cache, remaining fragments just cache data fragment, unref
RX pkt. So in both the cases caller can assume packet is consumed.
Parse size and tag from the fragment check if we have any cache related to it . If not create a new cache . Remove the fragmentation header and uncompress IPv6 and related headers . Cache Rx part of fragment along with data buf for the first fragment in the cache remaining fragments just cache data fragment unref RX pkt . So in both the cases caller can assume packet is consumed .
static inline enum net_verdict add_frag_to_cache(struct net_pkt *pkt,
						 bool first)
{
	struct frag_cache *cache;
	struct net_buf *frag;
	u16_t size;
	u16_t tag;
	u16_t offset = 0;
	u8_t pos = 0;
	size = get_datagram_size(pkt->frags->data);
	pos += NET_6LO_FRAG_DATAGRAM_SIZE_LEN;
	tag = get_datagram_tag(pkt->frags->data + pos);
	pos += NET_6LO_FRAG_DATAGRAM_OFFSET_LEN;
	if (!first) {
		offset = ((u16_t)pkt->frags->data[pos]) << 3;
		pos++;
	}
	remove_frag_header(pkt->frags, pos);
	if (first && !net_6lo_uncompress(pkt)) {
		NET_ERR("Could not uncompress first frag's 6lo hdr");
		clear_reass_cache(size, tag);
		return NET_DROP;
	}
	frag = pkt->frags;
	pkt->frags = NULL;
	cache = get_reass_cache(size, tag);
	if (!cache) {
		cache = set_reass_cache(pkt, size, tag);
		if (!cache) {
			NET_ERR("Could not get a cache entry");
			pkt->frags = frag;
			return NET_DROP;
		}
		if (!copy_frag(cache->pkt, frag, offset)) {
			pkt->frags = frag;
			cache->pkt = NULL;
			clear_reass_cache(size, tag);
			NET_ERR("Copying frag failed");
			return NET_DROP;
		}
		NET_DBG("packet inserted into cache");
		return NET_OK;
	}
	if (!copy_frag(cache->pkt, frag, offset)) {
		pkt->frags = frag;
		clear_reass_cache(size, tag);
		return NET_DROP;
	}
	if (net_pkt_get_len(cache->pkt) == size) {
		pkt->frags = cache->pkt->frags;
		cache->pkt->frags = NULL;
		update_protocol_header_lengths(pkt, cache->size);
		clear_reass_cache(size, tag);
		NET_DBG("All fragments received and reassembled");
		return NET_CONTINUE;
	}
	net_pkt_unref(pkt);
	return NET_OK;
}
static inline enum net_verdict add_frag_to_cache ( struct net_pkt * pkt , bool first ) { struct frag_cache * cache ; struct net_buf * frag ; u16_t size ; u16_t tag ; u16_t offset = 0 ; u8_t pos = 0 ; size = get_datagram_size ( pkt -> frags -> data ) ; pos += NET_6LO_FRAG_DATAGRAM_SIZE_LEN ; tag = get_datagram_tag ( pkt -> frags -> data + pos ) ; pos += NET_6LO_FRAG_DATAGRAM_OFFSET_LEN ; if ( ! first ) { offset = ( ( u16_t ) pkt -> frags -> data [ pos ] ) << 3 ; pos ++ ; } remove_frag_header ( pkt -> frags , pos ) ; if ( first && ! net_6lo_uncompress ( pkt ) ) { NET_ERR ( " " ) ; clear_reass_cache ( size , tag ) ; return NET_DROP ; } frag = pkt -> frags ; pkt -> frags = NULL ; cache = get_reass_cache ( size , tag ) ; if ( ! cache ) { cache = set_reass_cache ( pkt , size , tag ) ; if ( ! cache ) { NET_ERR ( " " ) ; pkt -> frags = frag ; return NET_DROP ; } if ( ! copy_frag ( cache -> pkt , frag , offset ) ) { pkt -> frags = frag ; cache -> pkt = NULL ; clear_reass_cache ( size , tag ) ; NET_ERR ( " " ) ; return NET_DROP ; } NET_DBG ( " " ) ; return NET_OK ; } if ( ! copy_frag ( cache -> pkt , frag , offset ) ) { pkt -> frags = frag ; clear_reass_cache ( size , tag ) ; return NET_DROP ; } if ( net_pkt_get_len ( cache -> pkt ) == size ) { pkt -> frags = cache -> pkt -> frags ; cache -> pkt -> frags = NULL ; update_protocol_header_lengths ( pkt , cache -> size ) ; clear_reass_cache ( size , tag ) ; NET_DBG ( " " ) ; return NET_CONTINUE ; } net_pkt_unref ( pkt ) ; return NET_OK ; }
Parse size and tag from the fragment, check if we have any cache
  related to it.
Parse size and tag from the fragment check if we have any cache related to it .
/* Parse total size of packet */ /* Parse the datagram tag */ /* Remove frag header and update data */ /* Uncompress the IP headers */ /* If there are no fragments in the cache means this frag
	 * is the first one. So cache Rx pkt otherwise not.
	 * Write data fragment data to cached Rx based on offset parameter.
	 * (Detach data fragment from incoming Rx and copy that data).
	 */ /* If write failed, then attach frag back to incoming packet
		 * and return NET_DROP, caller will take care of freeing it.
		 */ /* Initialize to NULL to prevent duble free. It's only
			 * needed here because this is the first fragment.
			 */ /* Add data packet to reassembly packet */ /* Check if all the fragments are received or not */ /* Assign frags back to input packet. */ /* Lengths are elided in compression, so calculate it. */ /* Once reassemble is done, cache is no longer needed. */ /* Unref Rx part of original packet */