/*
 * Copyright 2013, 2014		Maurice Leclaire <leclaire@in.tum.de>
 * 				Stephan M. Guenther <moepi@moepi.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * See COPYING for more details.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * \defgroup moep80211_frame Frame
 * \brief The Frame API contains the functioality used to manage frames.
 *
 * This is the generic API available for all frames. Specialized functions are
 * provided by the respective module.
 *
 * \{
 * \file
 */
#ifndef __MOEP80211_FRAME_H
#define __MOEP80211_FRAME_H

#include <stddef.h>

#include <moep80211/types.h>


struct moep_frame;

/**
 * \brief a moep frame
 *
 * This is the opaque representation of a frame.
 */
typedef struct moep_frame *moep_frame_t;


/**
 * \brief return payload of a frame
 *
 * The function moep_frame_get_payload() returns the payload associated with the
 * frame.
 *
 * \param frame the frame
 * \param len returns the length of the payload.
 *
 * \return This function returns a pointer to the payload or NULL if no payload
 * is associated with the frame.
 */
u8 *moep_frame_get_payload(moep_frame_t frame, size_t *len);

/**
 * \brief set payload of a frame
 *
 * The function moep_frame_set_payload() adds a payload to the frame. Any
 * payload previously set is freed. If \paramname{payload} is NULL only the
 * previous payload is removed. The content of \paramname{payload} is copied to
 * an internal buffer so that \paramname{payload} does not need to be preserved.
 *
 * \param frame the frame
 * \param payload a pointer to the payload
 * \param len the length of the payload
 *
 * \return This function returns a pointer to the internally saved payload.
 * \retval NULL on error (errno is set appropriately) or if \paramname{payload}
 * is NULL
 *
 * \errors{ }
 * \errval{ENOMEM, Not enough memory available.}
 * \enderrors
 */
u8 *moep_frame_set_payload(moep_frame_t frame, u8 *payload, size_t len);

/**
 * \brief adjust the len of the payload of a frame
 *
 * The function moep_frame_adjust_payload_len() changes the size of the payload
 * associated with the frame. If necessary the internal buffer is changed.
 *
 * \param frame the frame
 * \param len the new length of the payload
 *
 * \return This function returns a pointer to the new internal payload buffer.
 * \retval NULL on error (errno is set appropriately) or if \paramname{len} is 0
 *
 * \errors{ }
 * \errval{ENOMEM, Not enough memory available.}
 * \enderrors
 */
u8 *moep_frame_adjust_payload_len(moep_frame_t frame, size_t len);

/**
 * \brief decode a frame
 *
 * The function moep_frame_decode() decodes a frame from the buffer
 * \paramname{buf} and saves the parsed content inside \paramname{frame}.
 * This function needs a frame to be already created, so normally one would use
 * moep_dev_frame_decode().
 *
 * \param frame the frame to store data in
 * \param buf the buffer with the frame
 * \param buflen the length of the buffer
 *
 * \retval 0 on success
 * \retval -1 on error, errno is set appropriately.
 */
int moep_frame_decode(moep_frame_t frame, u8 *buf, size_t buflen);

/**
 * \brief encode a frame
 *
 * The function moep_frame_encode() encodes a frame to a buffer. This function
 * can be used in multiple ways:
 * \li if \paramname{buf} is NULL, only the length the frame would need is
 * returned.
 * \li if \paramname{*buf} is NULL and \paramname{buflen} is 0, an appropriate
 * buffer is allocated to hold the frame and returned in \paramname{buf}.
 * \li if \paramname{*buf} is NULL and \paramname{buflen} is not 0, a buffer
 * of at most \paramname{buflen} is allocated.
 * \li if \paramname{*buf} is not NULL, it will be used as buffer if it is big
 * enough to hold the frame.
 *
 * \param frame the frame to be encoded
 * \param buf a pointer to the buffer
 * \param buflen the length of the buffer
 *
 * \return This function returns the length of the encoded frame.
 *
 * \retval -1 on error, errno is set appropriately.
 *
 * \errors{These are some standard errors generated by this function. Additional
 * errors may be generated and returned from the underlying device specific
 * functions.}
 * \errval{EMSGSIZE, The buffer is too small to hold the encoded frame.}
 * \errval{ENOMEM, Not enough memory available.}
 * \enderrors
 */
int moep_frame_encode(moep_frame_t frame, u8 **buf, size_t buflen);

/**
 * \brief destroy a frame
 *
 * The function moep_frame_destroy() destroys a frame and releases its
 * associated ressources.
 *
 * \param frame the frame
 */
void moep_frame_destroy(moep_frame_t frame);

/** \} */
#endif /* __MOEP80211_FRAME_H */
