blob: 8003f8471defc081b238d2afd50bfec212acf6da [file] [log] [blame]
/** @file
* @brief L2 buffer API
*
* L2 (layer 2 or MAC layer) data is passed between application and
* IP stack via a l2_buf struct. Currently L2 buffers are only used
* in IEEE 802.15.4 code.
*/
/*
* Copyright (c) 2015 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Data buffer API - used for all data to/from net */
#ifndef __L2_BUF_H
#define __L2_BUF_H
#include <stdint.h>
#include <net/ip_buf.h>
#include "contiki/ip/uipopt.h"
#include "contiki/ip/uip.h"
#include "contiki/packetbuf.h"
#include "contiki/os/lib/list.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(CONFIG_L2_BUFFERS)
#ifdef CONFIG_NETWORKING_WITH_LOGGING
#undef DEBUG_L2_BUFS
#define DEBUG_L2_BUFS
#endif
/** @cond ignore */
void l2_buf_init(void);
/* @endcond */
/** For the MAC/L2 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_L2_BUF_MAX_SIZE
#define NET_L2_BUF_MAX_SIZE (PACKETBUF_SIZE + PACKETBUF_HDR_SIZE)
#endif
struct l2_buf {
/** @cond ignore */
/* 6LoWPAN pointers */
uint8_t *packetbuf_ptr;
uint8_t packetbuf_hdr_len;
uint8_t packetbuf_payload_len;
uint8_t uncomp_hdr_len;
int last_tx_status;
#if defined(CONFIG_NETWORKING_WITH_15_4)
LIST_STRUCT(neighbor_list);
#endif
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_packetbufptr;
/* @endcond */
};
/** @cond ignore */
#define uip_packetbuf_ptr(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->packetbuf_ptr)
#define uip_packetbuf_hdr_len(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->packetbuf_hdr_len)
#define uip_packetbuf_payload_len(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->packetbuf_payload_len)
#define uip_uncomp_hdr_len(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->uncomp_hdr_len)
#define uip_last_tx_status(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->last_tx_status)
#if defined(CONFIG_NETWORKING_WITH_15_4)
#define uip_neighbor_list(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->neighbor_list)
#endif
#define uip_pkt_buflen(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->pkt_buflen)
#define uip_pkt_bufptr(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->pkt_bufptr)
#define uip_pkt_hdrptr(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->pkt_hdrptr)
#define uip_pkt_packetbufptr(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->pkt_packetbufptr)
#define uip_pkt_packetbuf_attrs(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->pkt_packetbuf_attrs)
#define uip_pkt_packetbuf_addrs(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->pkt_packetbuf_addrs)
/* Note that we do not reserve extra space for the header when the packetbuf
* is converted to use net_buf, so the packet starts directly from the
* data pointer. This is done in order to simplify the 802.15.4 packet
* handling. So the L2 buffer should only be allocated by calling
* reserve function like this: l2_buf_get_reserve(0);
*/
#define uip_pkt_packetbuf(ptr) ((ptr)->data)
/* @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.
*/
#ifdef DEBUG_L2_BUFS
#define l2_buf_get_reserve(res) l2_buf_get_reserve_debug(res, \
__func__, __LINE__)
struct net_buf *l2_buf_get_reserve_debug(uint16_t reserve_head,
const char *caller, int line);
#else
struct net_buf *l2_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.
*
*/
#ifdef DEBUG_L2_BUFS
#define l2_buf_unref(buf) l2_buf_unref_debug(buf, __func__, __LINE__)
void l2_buf_unref_debug(struct net_buf *buf, const char *caller, int line);
#else
void l2_buf_unref(struct net_buf *buf);
#endif
#else /* defined(CONFIG_L2_BUFFERS) */
#define l2_buf_init(...)
#endif /* defined(CONFIG_L2_BUFFERS) */
#ifdef __cplusplus
}
#endif
#endif /* __L2_BUF_H */