/** @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 #include #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 */