151 lines
4.6 KiB
C
151 lines
4.6 KiB
C
/** @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"
|
|
|
|
#if defined(CONFIG_L2_BUFFERS)
|
|
|
|
#if defined(CONFIG_NET_BUF_DEBUG)
|
|
#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;
|
|
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_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)
|
|
#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) */
|
|
|
|
#endif /* __L2_BUF_H */
|