net: pkt: Add function to linearize a network packet

This helper copies desired amount of data from network packet
buffer info a user provided linear buffer.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2017-05-09 10:12:46 +03:00 committed by Anas Nashif
commit c77460da53
2 changed files with 59 additions and 0 deletions

View file

@ -842,6 +842,23 @@ static inline struct net_buf *net_pkt_copy_all(struct net_pkt *pkt,
int net_frag_linear_copy(struct net_buf *dst, struct net_buf *src,
u16_t offset, u16_t len);
/**
* @brief Copy len bytes from src starting from offset to dst buffer
*
* This routine assumes that dst is large enough to store @a len bytes
* starting from offset at src.
*
* @param dst Destination buffer
* @param dst_len Destination buffer max length
* @param src Source buffer that may be fragmented
* @param offset Starting point to copy from
* @param len Number of bytes to copy
* @return number of bytes copied if everything is ok
* @return -ENOMEM on error
*/
int net_frag_linearize(u8_t *dst, size_t dst_len,
struct net_pkt *src, u16_t offset, u16_t len);
/**
* @brief Compact the fragment list of a packet.
*

View file

@ -1015,6 +1015,48 @@ int net_frag_linear_copy(struct net_buf *dst, struct net_buf *src,
return 0;
}
int net_frag_linearize(u8_t *dst, size_t dst_len, struct net_pkt *src,
u16_t offset, u16_t len)
{
struct net_buf *frag;
u16_t to_copy;
u16_t copied;
if (dst_len < (size_t)len) {
return -ENOMEM;
}
frag = src->frags;
/* find the right fragment to start copying from */
while (frag && offset >= frag->len) {
offset -= frag->len;
frag = frag->frags;
}
/* traverse the fragment chain until len bytes are copied */
copied = 0;
while (frag && len > 0) {
to_copy = min(len, frag->len - offset);
memcpy(dst + copied, frag->data + offset, to_copy);
copied += to_copy;
/* to_copy is always <= len */
len -= to_copy;
frag = frag->frags;
/* after the first iteration, this value will be 0 */
offset = 0;
}
if (len > 0) {
return -ENOMEM;
}
return copied;
}
bool net_pkt_compact(struct net_pkt *pkt)
{
struct net_buf *frag, *prev;