|
|
|
/*
|
|
|
|
* Copyright 2013-2019 Software Radio Systems Limited
|
|
|
|
*
|
|
|
|
* This file is part of srsLTE.
|
|
|
|
*
|
|
|
|
* srsLTE is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License as
|
|
|
|
* published by the Free Software Foundation, either version 3 of
|
|
|
|
* the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* srsLTE 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 Affero General Public License for more details.
|
|
|
|
*
|
|
|
|
* A copy of the GNU Affero General Public License can be found in
|
|
|
|
* the LICENSE file in the top-level directory of this distribution
|
|
|
|
* and at http://www.gnu.org/licenses/.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SRSLTE_RLC_COMMON_H
|
|
|
|
#define SRSLTE_RLC_COMMON_H
|
|
|
|
|
|
|
|
#include "srslte/upper/rlc_interface.h"
|
|
|
|
|
|
|
|
namespace srslte {
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Structs and Defines
|
|
|
|
* Ref: 3GPP TS 36.322 v10.0.0
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#define RLC_AM_WINDOW_SIZE 512
|
|
|
|
#define RLC_MAX_SDU_SIZE ((1<<11)-1) // Length of LI field is 11bits
|
|
|
|
|
|
|
|
|
|
|
|
typedef enum{
|
|
|
|
RLC_FI_FIELD_START_AND_END_ALIGNED = 0,
|
|
|
|
RLC_FI_FIELD_NOT_END_ALIGNED,
|
|
|
|
RLC_FI_FIELD_NOT_START_ALIGNED,
|
|
|
|
RLC_FI_FIELD_NOT_START_OR_END_ALIGNED,
|
|
|
|
RLC_FI_FIELD_N_ITEMS,
|
|
|
|
}rlc_fi_field_t;
|
|
|
|
static const char rlc_fi_field_text[RLC_FI_FIELD_N_ITEMS][32] = {"Start and end aligned",
|
|
|
|
"Not end aligned",
|
|
|
|
"Not start aligned",
|
|
|
|
"Not start or end aligned"};
|
|
|
|
|
|
|
|
typedef enum{
|
|
|
|
RLC_DC_FIELD_CONTROL_PDU = 0,
|
|
|
|
RLC_DC_FIELD_DATA_PDU,
|
|
|
|
RLC_DC_FIELD_N_ITEMS,
|
|
|
|
}rlc_dc_field_t;
|
|
|
|
static const char rlc_dc_field_text[RLC_DC_FIELD_N_ITEMS][20] = {"Control PDU",
|
|
|
|
"Data PDU"};
|
|
|
|
|
|
|
|
// UMD PDU Header
|
|
|
|
typedef struct{
|
|
|
|
uint8_t fi; // Framing info
|
|
|
|
rlc_umd_sn_size_t sn_size; // Sequence number size (5 or 10 bits)
|
|
|
|
uint16_t sn; // Sequence number
|
|
|
|
uint32_t N_li; // Number of length indicators
|
|
|
|
uint16_t li[RLC_AM_WINDOW_SIZE]; // Array of length indicators
|
|
|
|
}rlc_umd_pdu_header_t;
|
|
|
|
|
|
|
|
// AMD PDU Header
|
|
|
|
struct rlc_amd_pdu_header_t{
|
|
|
|
rlc_dc_field_t dc; // Data or control
|
|
|
|
uint8_t rf; // Resegmentation flag
|
|
|
|
uint8_t p; // Polling bit
|
|
|
|
uint8_t fi; // Framing info
|
|
|
|
uint16_t sn; // Sequence number
|
|
|
|
uint8_t lsf; // Last segment flag
|
|
|
|
uint16_t so; // Segment offset
|
|
|
|
uint32_t N_li; // Number of length indicators
|
|
|
|
uint16_t li[RLC_AM_WINDOW_SIZE]; // Array of length indicators
|
|
|
|
|
|
|
|
rlc_amd_pdu_header_t(){
|
|
|
|
dc = RLC_DC_FIELD_CONTROL_PDU;
|
|
|
|
rf = 0;
|
|
|
|
p = 0;
|
|
|
|
fi = 0;
|
|
|
|
sn = 0;
|
|
|
|
lsf = 0;
|
|
|
|
so = 0;
|
|
|
|
N_li=0;
|
|
|
|
for(int i=0;i<RLC_AM_WINDOW_SIZE;i++)
|
|
|
|
li[i] = 0;
|
|
|
|
}
|
|
|
|
rlc_amd_pdu_header_t(const rlc_amd_pdu_header_t& h)
|
|
|
|
{
|
|
|
|
copy(h);
|
|
|
|
}
|
|
|
|
rlc_amd_pdu_header_t& operator= (const rlc_amd_pdu_header_t& h)
|
|
|
|
{
|
|
|
|
copy(h);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
void copy(const rlc_amd_pdu_header_t& h)
|
|
|
|
{
|
|
|
|
dc = h.dc;
|
|
|
|
rf = h.rf;
|
|
|
|
p = h.p;
|
|
|
|
fi = h.fi;
|
|
|
|
sn = h.sn;
|
|
|
|
lsf = h.lsf;
|
|
|
|
so = h.so;
|
|
|
|
N_li = h.N_li;
|
|
|
|
for(uint32_t i=0;i<h.N_li;i++)
|
|
|
|
li[i] = h.li[i];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// NACK helper
|
|
|
|
struct rlc_status_nack_t{
|
|
|
|
uint16_t nack_sn;
|
|
|
|
bool has_so;
|
|
|
|
uint16_t so_start;
|
|
|
|
uint16_t so_end;
|
|
|
|
|
|
|
|
rlc_status_nack_t(){has_so=false; nack_sn=0; so_start=0; so_end=0;}
|
|
|
|
};
|
|
|
|
|
|
|
|
// STATUS PDU
|
|
|
|
struct rlc_status_pdu_t{
|
|
|
|
uint16_t ack_sn;
|
|
|
|
uint32_t N_nack;
|
|
|
|
rlc_status_nack_t nacks[RLC_AM_WINDOW_SIZE];
|
|
|
|
|
|
|
|
rlc_status_pdu_t(){N_nack=0; ack_sn=0;}
|
|
|
|
};
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* RLC Common interface
|
|
|
|
* Common interface for all RLC entities
|
|
|
|
***************************************************************************/
|
|
|
|
class rlc_common
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
// Size of the Uplink buffer in number of PDUs
|
|
|
|
const static int RLC_BUFFER_NOF_PDU = 128;
|
|
|
|
|
|
|
|
virtual ~rlc_common() {}
|
|
|
|
virtual void init(srslte::log *rlc_entity_log_,
|
|
|
|
uint32_t lcid_,
|
|
|
|
srsue::pdcp_interface_rlc *pdcp_,
|
|
|
|
srsue::rrc_interface_rlc *rrc_,
|
|
|
|
srslte::mac_interface_timers *mac_timers_) = 0;
|
|
|
|
virtual bool configure(srslte_rlc_config_t cnfg) = 0;
|
|
|
|
virtual void stop() = 0;
|
|
|
|
virtual void reestablish() = 0;
|
|
|
|
virtual void empty_queue() = 0;
|
|
|
|
|
|
|
|
virtual rlc_mode_t get_mode() = 0;
|
|
|
|
virtual uint32_t get_bearer() = 0;
|
|
|
|
|
|
|
|
virtual uint32_t get_num_tx_bytes() = 0;
|
|
|
|
virtual uint32_t get_num_rx_bytes() = 0;
|
|
|
|
virtual void reset_metrics() = 0;
|
|
|
|
|
|
|
|
// PDCP interface
|
|
|
|
virtual void write_sdu(unique_byte_buffer sdu, bool blocking) = 0;
|
|
|
|
|
|
|
|
// MAC interface
|
|
|
|
virtual bool has_data() = 0;
|
|
|
|
virtual uint32_t get_buffer_state() = 0;
|
|
|
|
virtual int read_pdu(uint8_t *payload, uint32_t nof_bytes) = 0;
|
|
|
|
virtual void write_pdu(uint8_t *payload, uint32_t nof_bytes) = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace srslte
|
|
|
|
|
|
|
|
#endif // SRSLTE_RLC_COMMON_H
|