mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-08-27 11:45:22 +00:00
IP packet passing through 6lowpan compression and 802.15.4 fragmentation has an issue. (RFC 6282 and 4944) RFC4944, 5.3 says "fragment header's datagram_size and datagram_offset values as the size and offset of the IPv6 datagram before compression". At the moment datagram size and offset values are after compression. Due to multiple bearer (15.4 and bluetooth) support and multiple incoming buffers support functionality is divided to compression and fragmentation parts. And datagram size and offset values for BT are after compression. Small packet (which doesn't need fragmentation) doesn't go through this. So cacheing compressed and uncompressed header lengths and with hdr difference preparing fragments as per original buffer (total buf size and offset). Change-Id: I9d3b0433e64964c68519d7c007cc06ec6035b573 Jira: ZEP-208 Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>
167 lines
4.9 KiB
C
167 lines
4.9 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"
|
|
#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 */
|