zephyr/include/net/net_buf.h

320 lines
10 KiB
C

/** @file
@brief Network buffer API
Network data is passed between application and IP stack via
a net_buf struct.
*/
/*
* Copyright (c) 2015 Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3) Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* Data buffer API - used for all data to/from net */
#ifndef __NET_BUF_H
#define __NET_BUF_H
#include <stdint.h>
#include "contiki/ip/uipopt.h"
#include "contiki/ip/uip.h"
#include "contiki/packetbuf.h"
#if defined(CONFIG_NETWORKING_WITH_LOGGING)
#undef DEBUG_NET_BUFS
#define DEBUG_NET_BUFS
#endif
struct net_context;
/** The default MTU is 1280 (minimum IPv6 packet size) + LL header
* In Contiki terms this is UIP_LINK_MTU + UIP_LLH_LEN = UIP_BUFSIZE
*
* Contiki assumes that this value is UIP_BUFSIZE so do not change it
* without changing the value of UIP_BUFSIZE!
*/
#define NET_BUF_MAX_DATA UIP_BUFSIZE
struct net_buf {
/** @cond ignore */
/* FIFO uses first 4 bytes itself, reserve space */
int __unused;
/* @endcond */
/** Network connection context */
struct net_context *context;
/** @cond ignore */
/* uIP stack specific data */
uint8_t uip_ext_len;
uint8_t uip_ext_bitmap;
uint8_t uip_ext_opt_offset;
uint8_t uip_flags;
uint16_t uip_slen;
uint16_t uip_appdatalen;
uint8_t *uip_next_hdr;
void *uip_appdata; /* application data */
void *uip_sappdata; /* app data to be sent */
void *uip_conn;
void *uip_udp_conn;
linkaddr_t dest;
linkaddr_t src;
/* Neighbor discovery vars */
void *nd6_opt_prefix_info;
void *nd6_prefix;
void *nd6_nbr;
void *nd6_defrt;
void *nd6_ifaddr;
uint8_t *nd6_opt_llao;
uip_ipaddr_t ipaddr;
uint8_t nd6_opt_offset;
/* @endcond */
/** Buffer data length */
uint16_t len;
/** Buffer head pointer */
uint8_t *data;
/** Actual network buffer storage */
uint8_t buf[NET_BUF_MAX_DATA];
};
/** @cond ignore */
/* Macros to access net_buf when inside Contiki stack */
#define uip_buf(buf) ((buf)->buf)
#define uip_len(buf) ((buf)->len)
#define uip_slen(buf) ((buf)->uip_slen)
#define uip_ext_len(buf) ((buf)->uip_ext_len)
#define uip_ext_bitmap(buf) ((buf)->uip_ext_bitmap)
#define uip_ext_opt_offset(buf) ((buf)->uip_ext_opt_offset)
#define uip_nd6_opt_offset(buf) ((buf)->nd6_opt_offset)
#define uip_next_hdr(buf) ((buf)->uip_next_hdr)
#define uip_appdata(buf) ((buf)->uip_appdata)
#define uip_appdatalen(buf) ((buf)->uip_appdatalen)
#define uip_sappdata(buf) ((buf)->uip_sappdata)
#define uip_flags(buf) ((buf)->uip_flags)
#define uip_conn(buf) ((struct uip_conn *)((buf)->uip_conn))
#define uip_set_conn(buf) ((buf)->uip_conn)
#define uip_udp_conn(buf) ((struct uip_udp_conn *)((buf)->uip_udp_conn))
#define uip_set_udp_conn(buf) ((buf)->uip_udp_conn)
#define uip_nd6_opt_prefix_info(buf) ((uip_nd6_opt_prefix_info *)((buf)->nd6_opt_prefix_info))
#define uip_set_nd6_opt_prefix_info(buf) ((buf)->nd6_opt_prefix_info)
#define uip_prefix(buf) ((uip_ds6_prefix_t *)((buf)->nd6_prefix))
#define uip_set_prefix(buf) ((buf)->nd6_prefix)
#define uip_nbr(buf) ((uip_ds6_nbr_t *)((buf)->nd6_nbr))
#define uip_set_nbr(buf) ((buf)->nd6_nbr)
#define uip_defrt(buf) ((uip_ds6_defrt_t *)((buf)->nd6_defrt))
#define uip_set_defrt(buf) ((buf)->nd6_defrt)
#define uip_addr(buf) ((uip_ds6_addr_t *)((buf)->nd6_ifaddr))
#define uip_set_addr(buf) ((buf)->nd6_ifaddr)
#define uip_nd6_opt_llao(buf) ((buf)->nd6_opt_llao)
#define uip_set_nd6_opt_llao(buf) ((buf)->nd6_opt_llao)
#define uip_nd6_ipaddr(buf) ((buf)->ipaddr)
/* @endcond */
/**
* @brief Get buffer from the available buffers pool.
*
* @details Get network buffer from buffer pool. You must have
* network context before able to use this function.
*
* @param context Network context that will be related to
* this buffer.
*
* @return Network buffer if successful, NULL otherwise.
*/
/* Get buffer from the available buffers pool */
#ifdef DEBUG_NET_BUFS
#define net_buf_get(context) net_buf_get_debug(context, __FUNCTION__, __LINE__)
struct net_buf *net_buf_get_debug(struct net_context *context, const char *caller, int line);
#else
struct net_buf *net_buf_get(struct net_context *context);
#endif
/**
* @brief Get buffer from pool but also reserve headroom for
* potential headers.
*
* @details Normally this version is not useful for applications
* but is mainly used by network fragmentation code.
*
* @param reserve How many bytes to reserve for headroom.
*
* @return Network buffer if successful, NULL otherwise.
*/
/* Same as net_buf_get, but also reserve headroom for potential headers */
#ifdef DEBUG_NET_BUFS
#define net_buf_get_reserve(res) net_buf_get_reserve_debug(res,__FUNCTION__,__LINE__)
struct net_buf *net_buf_get_reserve_debug(uint16_t reserve_head, const char *caller, int line);
#else
struct net_buf *net_buf_get_reserve(uint16_t reserve_head);
#endif
/**
* @brief Place buffer back into the available buffers pool.
*
* @details Releases the buffer to other use. This needs to be
* called by application after it has finished with
* the buffer.
*
* @param buf Network buffer to release.
*
*/
/* Place buffer back into the available buffers pool */
#ifdef DEBUG_NET_BUFS
#define net_buf_put(buf) net_buf_put_debug(buf, __FUNCTION__, __LINE__)
void net_buf_put_debug(struct net_buf *buf, const char *caller, int line);
#else
void net_buf_put(struct net_buf *buf);
#endif
/**
* @brief Prepare data to be added at the end of the buffer.
*
* @details Move the tail pointer forward.
*
* @param buf Network buffer.
* @param len Size of data to be added.
*
* @return Pointer to new tail.
*/
uint8_t *net_buf_add(struct net_buf *buf, uint16_t len);
/**
* @brief Push data to the beginning of the buffer.
*
* @details Move the data pointer backwards.
*
* @param buf Network buffer.
* @param len Size of data to be added.
*
* @return Pointer to new head.
*/
uint8_t *net_buf_push(struct net_buf *buf, uint16_t len);
/**
* @brief Remove data from the beginning of the buffer.
*
* @details Move the data pointer forward.
*
* @param buf Network buffer.
* @param len Size of data to be removed.
*
* @return Pointer to new head.
*/
uint8_t *net_buf_pull(struct net_buf *buf, uint16_t len);
/** @def net_buf_tail
*
* @brief Return pointer to the end of the data in the buffer.
*
* @details This macro returns the tail of the buffer.
*
* @param buf Network buffer.
*
* @return Pointer to tail.
*/
#define net_buf_tail(buf) ((buf)->data + (buf)->len)
/** @cond ignore */
void net_buf_init(void);
/* @endcond */
/** For the MAC layer (after the IPv6 packet is fragmented to smaller
* chunks), we can use much smaller buffers (depending on used radio
* technology). For 802.15.4 we use the 128 bytes long buffers.
*/
#ifndef NET_MAC_BUF_MAX_SIZE
#define NET_MAC_BUF_MAX_SIZE PACKETBUF_SIZE
#endif
struct net_mbuf {
/** @cond ignore */
/* FIFO uses first 4 bytes itself, reserve space */
int __unused;
/* @endcond */
/** @cond ignore */
/* 6LoWPAN pointers */
uint8_t *packetbuf_ptr;
uint8_t packetbuf_hdr_len;
int packetbuf_payload_len;
uint8_t uncomp_hdr_len;
int last_tx_status;
struct packetbuf_attr pkt_packetbuf_attrs[PACKETBUF_NUM_ATTRS];
struct packetbuf_addr pkt_packetbuf_addrs[PACKETBUF_NUM_ADDRS];
uint16_t pkt_buflen, pkt_bufptr;
uint8_t pkt_hdrptr;
uint8_t pkt_packetbuf[PACKETBUF_SIZE + PACKETBUF_HDR_SIZE];
uint8_t *pkt_packetbufptr;
/* @endcond */
};
/**
* @brief Get buffer from the available buffers pool
* and also reserve headroom for potential headers.
*
* @details Normally this version is not useful for applications
* but is mainly used by network fragmentation code.
*
* @param reserve How many bytes to reserve for headroom.
*
* @return Network buffer if successful, NULL otherwise.
*/
struct net_mbuf *net_mbuf_get_reserve(uint16_t reserve_head);
/**
* @brief Place buffer back into the available buffers pool.
*
* @details Releases the buffer to other use. This needs to be
* called by application after it has finished with
* the buffer.
*
* @param buf Network buffer to release.
*/
void net_mbuf_put(struct net_mbuf *buf);
/** @cond ignore */
#define uip_packetbuf_ptr(buf) ((buf)->packetbuf_ptr)
#define uip_packetbuf_hdr_len(buf) ((buf)->packetbuf_hdr_len)
#define uip_packetbuf_payload_len(buf) ((buf)->packetbuf_payload_len)
#define uip_uncomp_hdr_len(buf) ((buf)->uncomp_hdr_len)
#define uip_last_tx_status(buf) ((buf)->last_tx_status)
#define uip_pkt_buflen(buf) ((buf)->pkt_buflen)
#define uip_pkt_bufptr(buf) ((buf)->pkt_bufptr)
#define uip_pkt_hdrptr(buf) ((buf)->pkt_hdrptr)
#define uip_pkt_packetbuf(buf) ((buf)->pkt_packetbuf)
#define uip_pkt_packetbufptr(buf) ((buf)->pkt_packetbufptr)
#define uip_pkt_packetbuf_attrs(buf) ((buf)->pkt_packetbuf_attrs)
#define uip_pkt_packetbuf_addrs(buf) ((buf)->pkt_packetbuf_addrs)
/* @endcond */
#endif /* __NET_BUF_H */