/*******************************************************************************

Eurecom OpenAirInterface 2
Copyright(c) 1999 - 2010 Eurecom

This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.

This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.

The full GNU General Public License is included in this distribution in
the file called "COPYING".

Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums       : http://forums.eurecom.fsr/openairinterface
Address      : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France

*******************************************************************************/
/*! \file rlc_am.h
* \brief This file, and only this file must be included by code that interact with RLC AM layer.
* \author GAUTHIER Lionel
* \date 2010-2011
* \version
* \note
* \bug
* \warning
*/
/** @defgroup _rlc_am_impl_ RLC AM Layer Reference Implementation
* @ingroup _rlc_impl_
* @{
*/

#    ifndef __RLC_AM_H__
#        define __RLC_AM_H__
#        ifdef RLC_AM_C
#            define private_rlc_am(x)
#            define protected_rlc_am(x)
#            define public_rlc_am(x)
#        else
#            ifdef RLC_AM_MODULE
#                define private_rlc_am(x)
#                define protected_rlc_am(x)  extern x
#                define public_rlc_am(x)     extern x
#            else
#                define private_rlc_am(x)
#                define protected_rlc_am(x)
#                define public_rlc_am(x)     extern x
#            endif
#        endif
#        include "platform_types.h"
#        include "rlc_def.h"
#        include "rlc_def_lte.h"
#        include "rlc_am_constants.h"
#        include "rlc_am_structs.h"
#        include "rlc_am_entity.h"
#        include "rlc_am_windows.h"
#        include "mem_block.h"
#        include "rlc_am_in_sdu.h"
#        include "rlc_am_segment.h"
#        include "rlc_am_segments_holes.h"
#        include "rlc_am_timer_poll_retransmit.h"
#        include "rlc_am_timer_reordering.h"
#        include "rlc_am_timer_status_prohibit.h"
#        include "rlc_am_retransmit.h"
#        include "rlc_am_receiver.h"
#        include "rlc_am_status_report.h"
#        include "rlc_am_rx_list.h"
#        include "rlc_am_reassembly.h"
#        include "rlc_am_init.h"
#        include "RLC-Config.h"
//#        include "rlc_am_test.h"

#ifdef USER_MODE
//#        include "rlc_am_very_simple_test.h"
#endif



/*! \fn void     rlc_am_release (rlc_am_entity_t *rlcP)
* \brief    Empty function, TO DO.
* \param[in]  rlcP                      RLC AM protocol instance pointer.
*/
public_rlc_am(void     rlc_am_release (rlc_am_entity_t *rlcP);)

/** @addtogroup _rlc_am_init_impl_
* @{
*/

/*! \fn void config_req_rlc_am (rlc_am_entity_t *rlcP, u32_t frame, u8_t eNB_flagP, module_id_t module_idP, rlc_am_info_t * config_amP, rb_id_t rb_idP, rb_type_t rb_typeP)
* \brief    Configure the UL and DL parameters of the RLC AM
* \param[in]  rlcP                      RLC AM protocol instance pointer.
* \param[in]  frame                     Frame index.
* \param[in]  eNB_flag                  Flag to indicate eNB (1) or UE (0)
* \param[in]  module_idP                Virtualized module identifier.
* \param[in]  config_amP                Configuration parameters for RLC AM instance.
* \param[in]  rb_idP                    Radio bearer identifier.
* \param[in]  rb_typeP                  Radio bearer type (Signalling or Data).
*/
public_rlc_am(void     config_req_rlc_am (rlc_am_entity_t *rlcP, u32_t frame, u8_t eNB_flagP, module_id_t module_idP, rlc_am_info_t * config_amP, rb_id_t rb_idP, rb_type_t rb_typeP);)

/*! \fn void config_req_rlc_am_asn1 (rlc_am_entity_t *rlcP, u32_t frame, u8_t eNB_flagP, module_id_t module_idP, struct RLC_Config__am * config_amP, rb_id_t rb_idP, rb_type_t rb_typeP)
* \brief    Configure the UL and DL parameters of the RLC AM with the asn1c autogenerated pameters structs
* \param[in]  rlcP                      RLC AM protocol instance pointer.
* \param[in]  frame                     Frame index.
* \param[in]  eNB_flag                  Flag to indicate eNB (1) or UE (0)
* \param[in]  module_idP                Virtualized module identifier.
* \param[in]  config_amP                Configuration parameters for RLC AM instance.
* \param[in]  rb_idP                    Radio bearer identifier.
* \param[in]  rb_typeP                  Radio bearer type (Signalling or Data).
*/
public_rlc_am(void config_req_rlc_am_asn1 (rlc_am_entity_t *rlcP, u32_t frame, u8_t eNB_flagP, module_id_t module_idP, struct RLC_Config__am * config_amP, rb_id_t rb_idP, rb_type_t rb_typeP);)

/** @} */

/*! \fn void     rlc_am_stat_req     (rlc_am_entity_t *rlcP,
                        unsigned int* stat_tx_pdcp_sdu,
                        unsigned int* stat_tx_pdcp_bytes,
                        unsigned int* stat_tx_pdcp_sdu_discarded,
                        unsigned int* stat_tx_pdcp_bytes_discarded,
                        unsigned int* stat_tx_data_pdu,
                        unsigned int* stat_tx_data_bytes,
                        unsigned int* stat_tx_retransmit_pdu_by_status,
                        unsigned int* stat_tx_retransmit_bytes_by_status,
                        unsigned int* stat_tx_retransmit_pdu,
                        unsigned int* stat_tx_retransmit_bytes,
                        unsigned int* stat_tx_control_pdu,
                        unsigned int* stat_tx_control_bytes,
                        unsigned int* stat_rx_pdcp_sdu,
                        unsigned int* stat_rx_pdcp_bytes,
                        unsigned int* stat_rx_data_pdus_duplicate,
                        unsigned int* stat_rx_data_bytes_duplicate,
                        unsigned int* stat_rx_data_pdu,
                        unsigned int* stat_rx_data_bytes,
                        unsigned int* stat_rx_data_pdu_dropped,
                        unsigned int* stat_rx_data_bytes_dropped,
                        unsigned int* stat_rx_data_pdu_out_of_window,
                        unsigned int* stat_rx_data_bytes_out_of_window,
                        unsigned int* stat_rx_control_pdu,
                        unsigned int* stat_rx_control_bytes,
                        unsigned int* stat_timer_reordering_timed_out,
                        unsigned int* stat_timer_poll_retransmit_timed_out,
                        unsigned int* stat_timer_status_prohibit_timed_out)
* \brief    Request TX and RX statistics of a RLC AM protocol instance.
* \param[in]  rlcP                                 RLC AM protocol instance pointer.
* \param[out] stat_tx_pdcp_sdu                     Number of SDUs coming from upper layers.
* \param[out] stat_tx_pdcp_bytes                   Number of bytes coming from upper layers.
* \param[out] stat_tx_pdcp_sdu_discarded           Number of discarded SDUs coming from upper layers.
* \param[out] stat_tx_pdcp_bytes_discarded         Number of discarded bytes coming from upper layers.
* \param[out] stat_tx_data_pdu                     Number of transmitted data PDUs to lower layers.
* \param[out] stat_tx_data_bytes                   Number of transmitted data bytes to lower layers.
* \param[out] stat_tx_retransmit_pdu_by_status     Number of re-transmitted data PDUs due to status reception.
* \param[out] stat_tx_retransmit_bytes_by_status   Number of re-transmitted data bytes due to status reception.
* \param[out] stat_tx_retransmit_pdu               Number of re-transmitted data PDUs to lower layers.
* \param[out] stat_tx_retransmit_bytes             Number of re-transmitted data bytes to lower layers.
* \param[out] stat_tx_control_pdu                  Number of transmitted control PDUs to lower layers.
* \param[out] stat_tx_control_bytes                Number of transmitted control bytes to lower layers.
* \param[out] stat_rx_pdcp_sdu                     Number of SDUs delivered to upper layers.
* \param[out] stat_rx_pdcp_bytes                   Number of bytes delivered to upper layers.
* \param[out] stat_rx_data_pdus_duplicate          Number of duplicate PDUs received.
* \param[out] stat_rx_data_bytes_duplicate         Number of duplicate bytes received.
* \param[out] stat_rx_data_pdu                     Number of received PDUs from lower layers.
* \param[out] stat_rx_data_bytes                   Number of received bytes from lower layers.
* \param[out] stat_rx_data_pdu_dropped             Number of received PDUs from lower layers, then dropped.
* \param[out] stat_rx_data_bytes_dropped           Number of received bytes from lower layers, then dropped.
* \param[out] stat_rx_data_pdu_out_of_window       Number of data PDUs received out of the receive window.
* \param[out] stat_rx_data_bytes_out_of_window     Number of data bytes received out of the receive window.
* \param[out] stat_rx_control_pdu                  Number of control PDUs received.
* \param[out] stat_rx_control_bytes                Number of control bytes received.
* \param[out] stat_timer_reordering_timed_out      Number of times the timer "reordering" has timed-out.
* \param[out] stat_timer_poll_retransmit_timed_out Number of times the timer "poll_retransmit" has timed-out.
* \param[out] stat_timer_status_prohibit_timed_out Number of times the timer "status_prohibit" has timed-out.
*/
public_rlc_am(void     rlc_am_stat_req     (rlc_am_entity_t *rlcP,
                        unsigned int* stat_tx_pdcp_sdu,
                        unsigned int* stat_tx_pdcp_bytes,
                        unsigned int* stat_tx_pdcp_sdu_discarded,
                        unsigned int* stat_tx_pdcp_bytes_discarded,
                        unsigned int* stat_tx_data_pdu,
                        unsigned int* stat_tx_data_bytes,
                        unsigned int* stat_tx_retransmit_pdu_by_status,
                        unsigned int* stat_tx_retransmit_bytes_by_status,
                        unsigned int* stat_tx_retransmit_pdu,
                        unsigned int* stat_tx_retransmit_bytes,
                        unsigned int* stat_tx_control_pdu,
                        unsigned int* stat_tx_control_bytes,
                        unsigned int* stat_rx_pdcp_sdu,
                        unsigned int* stat_rx_pdcp_bytes,
                        unsigned int* stat_rx_data_pdus_duplicate,
                        unsigned int* stat_rx_data_bytes_duplicate,
                        unsigned int* stat_rx_data_pdu,
                        unsigned int* stat_rx_data_bytes,
                        unsigned int* stat_rx_data_pdu_dropped,
                        unsigned int* stat_rx_data_bytes_dropped,
                        unsigned int* stat_rx_data_pdu_out_of_window,
                        unsigned int* stat_rx_data_bytes_out_of_window,
                        unsigned int* stat_rx_control_pdu,
                        unsigned int* stat_rx_control_bytes,
                        unsigned int* stat_timer_reordering_timed_out,
                        unsigned int* stat_timer_poll_retransmit_timed_out,
                        unsigned int* stat_timer_status_prohibit_timed_out);)

/*! \fn void     rlc_am_get_pdus (void *rlcP)
* \brief    Request the segmentation of SDUs based on status previously sent by MAC.
* \param[in]  rlcP                      RLC AM protocol instance pointer.
*/
private_rlc_am(   void     rlc_am_get_pdus (void *argP);)

/*! \fn void rlc_am_rx (void *rlcP, u32_t frame, u8_t eNB_flag, struct mac_data_ind data_indication)
* \brief    Process the received PDUs from lower layer.
* \param[in]  rlcP                      RLC AM protocol instance pointer.
* \param[in]  frame                     Frame index.
* \param[in]  eNB_flag                  Flag to indicate eNB (1) or UE (0).
* \param[in]  data_indication           PDUs from MAC.
*/
protected_rlc_am( void     rlc_am_rx (void *, u32_t frame, struct mac_data_ind);)

/*! \fn struct mac_status_resp rlc_am_mac_status_indication (void *rlcP, u32_t frame,u16_t tbs_sizeP, struct mac_status_ind tx_statusP)
* \brief    Request the maximum number of bytes that can be served by RLC instance to MAC and fix the amount of bytes requested by MAC for next RLC transmission.
* \param[in]  rlcP                      RLC AM protocol instance pointer.
* \param[in]  frame                     Frame index.
* \param[in]  tbs_sizeP                 Number of bytes requested by MAC for next transmission.
* \param[in]  tx_statusP                Transmission status given by MAC on previous MAC transmission of the PDU.
* \return     The maximum number of bytes that can be served by RLC instance to MAC.
*/
public_rlc_am(    struct mac_status_resp rlc_am_mac_status_indication (void *rlcP, u32_t frame, u16_t tbs_sizeP, struct mac_status_ind tx_statusP);)

/*! \fn struct mac_data_req rlc_am_mac_data_request (void *rlcP, u32_t frame)
* \brief    Gives PDUs to lower layer MAC.
* \param[in]  rlcP                      RLC AM protocol instance pointer.
* \param[in]  frame                     Frame index.
* \return     A PDU of the previously requested number of bytes, and the updated maximum number of bytes that can be served by RLC instance to MAC for next RLC transmission.
*/
public_rlc_am(    struct mac_data_req rlc_am_mac_data_request (void *rlcP, u32_t frame);)

/*! \fn void     rlc_am_mac_data_indication (void *rlcP, u32_t frame, u8_t eNB_flag, struct mac_data_ind data_indP)
* \brief    Receive PDUs from lower layer MAC.
* \param[in]  rlcP             RLC UM protocol instance pointer.
* \param[in]  frame            Frame index.
* \param[in]  eNB_flag         Flag to indicate eNB (1) or UE (0).
* \param[in]  data_indP        PDUs from MAC.
*/
public_rlc_am(    void     rlc_am_mac_data_indication (void *rlcP, u32_t frame, u8_t eNB_flag, struct mac_data_ind data_indP);)

/*! \fn void     rlc_am_data_req (void *rlcP, u32_t frame, mem_block_t *sduP)
* \brief    Interface with higher layers, buffer higher layer SDUS for transmission.
* \param[in]  rlcP             RLC AM protocol instance pointer.
* \param[in]  frame            Frame index.
* \param[in]  sduP             SDU. (A struct rlc_am_data_req is mapped on sduP->data.)
*/
public_rlc_am(    void     rlc_am_data_req (void *rlcP, u32_t frame, mem_block_t *sduP);)
/** @} */
#    endif
