net: buf: Add net_buf_id() API

Add a net_buf_id() API which translates a buffer into a zero-based
index, based on its placement in the buffer pool. This can be useful
if you want to associate an external array of meta-data contexts with
the buffers of a pool.

The added value of this API is slightly limited at the moment, since
the net_buf API allows custom user-data sizes for each pool (i.e. the
user data can be used instead of a separately allocated meta-data
array). However, there's some refactoring coming soon which will unify
all net_buf structs to have the same fixed (and typically small)
amount of user data. In such cases it may be desirable to have
external user data in order not to inflate all buffers in the system
because of a single pool needing the extra memory.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
diff --git a/include/net/buf.h b/include/net/buf.h
index 39f4863..57348eb 100644
--- a/include/net/buf.h
+++ b/include/net/buf.h
@@ -553,6 +553,20 @@
 struct net_buf_pool *net_buf_pool_get(int id);
 
 /**
+ *  @brief Get a zero-based index for a buffer.
+ *
+ *  This function will translate a buffer into a zero-based index,
+ *  based on its placement in its buffer pool. This can be useful if you
+ *  want to associate an external array of meta-data contexts with the
+ *  buffers of a pool.
+ *
+ *  @param buf  Network buffer.
+ *
+ *  @return Zero-based index for the buffer.
+ */
+int net_buf_id(struct net_buf *buf);
+
+/**
  *  @brief Allocate a new buffer from a pool.
  *
  *  Allocate a new buffer from a pool.
diff --git a/subsys/net/buf.c b/subsys/net/buf.c
index 2e1fa01..9b22e5a 100644
--- a/subsys/net/buf.c
+++ b/subsys/net/buf.c
@@ -64,6 +64,15 @@
 #define UNINIT_BUF(pool, n) (struct net_buf *)(((u8_t *)(pool->__bufs)) + \
 					       ((n) * BUF_SIZE(pool)))
 
+int net_buf_id(struct net_buf *buf)
+{
+	struct net_buf_pool *pool = net_buf_pool_get(buf->pool_id);
+	u8_t *pool_start = (u8_t *)pool->__bufs;
+	u8_t *buf_ptr = (u8_t *)buf;
+
+	return (buf_ptr - pool_start) / BUF_SIZE(pool);
+}
+
 static inline struct net_buf *pool_get_uninit(struct net_buf_pool *pool,
 					      u16_t uninit_count)
 {