|
|
@ -210,12 +210,10 @@ rlc_am_lte::rlc_am_lte_tx::rlc_am_lte_tx(rlc_am_lte* parent_) :
|
|
|
|
poll_retx_timer(parent_->timers->get_unique_timer()),
|
|
|
|
poll_retx_timer(parent_->timers->get_unique_timer()),
|
|
|
|
status_prohibit_timer(parent_->timers->get_unique_timer())
|
|
|
|
status_prohibit_timer(parent_->timers->get_unique_timer())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_mutex_init(&mutex, NULL);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
rlc_am_lte::rlc_am_lte_tx::~rlc_am_lte_tx()
|
|
|
|
rlc_am_lte::rlc_am_lte_tx::~rlc_am_lte_tx()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_mutex_destroy(&mutex);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void rlc_am_lte::rlc_am_lte_tx::set_bsr_callback(bsr_callback_t callback)
|
|
|
|
void rlc_am_lte::rlc_am_lte_tx::set_bsr_callback(bsr_callback_t callback)
|
|
|
@ -262,7 +260,7 @@ void rlc_am_lte::rlc_am_lte_tx::stop()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
empty_queue();
|
|
|
|
empty_queue();
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
|
|
|
|
|
|
|
|
|
|
tx_enabled = false;
|
|
|
|
tx_enabled = false;
|
|
|
|
|
|
|
|
|
|
|
@ -290,13 +288,11 @@ void rlc_am_lte::rlc_am_lte_tx::stop()
|
|
|
|
|
|
|
|
|
|
|
|
// Drop all SDU info in queue
|
|
|
|
// Drop all SDU info in queue
|
|
|
|
undelivered_sdu_info_queue.clear();
|
|
|
|
undelivered_sdu_info_queue.clear();
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void rlc_am_lte::rlc_am_lte_tx::empty_queue()
|
|
|
|
void rlc_am_lte::rlc_am_lte_tx::empty_queue()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
|
|
|
|
|
|
|
|
|
|
// deallocate all SDUs in transmit queue
|
|
|
|
// deallocate all SDUs in transmit queue
|
|
|
|
while (tx_sdu_queue.size() > 0) {
|
|
|
|
while (tx_sdu_queue.size() > 0) {
|
|
|
@ -305,8 +301,6 @@ void rlc_am_lte::rlc_am_lte_tx::empty_queue()
|
|
|
|
|
|
|
|
|
|
|
|
// deallocate SDU that is currently processed
|
|
|
|
// deallocate SDU that is currently processed
|
|
|
|
tx_sdu.reset();
|
|
|
|
tx_sdu.reset();
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void rlc_am_lte::rlc_am_lte_tx::reestablish()
|
|
|
|
void rlc_am_lte::rlc_am_lte_tx::reestablish()
|
|
|
@ -350,7 +344,7 @@ void rlc_am_lte::rlc_am_lte_tx::check_sn_reached_max_retx(uint32_t sn)
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state()
|
|
|
|
uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
|
|
uint32_t n_bytes = 0;
|
|
|
|
uint32_t n_bytes = 0;
|
|
|
|
uint32_t n_sdus = 0;
|
|
|
|
uint32_t n_sdus = 0;
|
|
|
|
|
|
|
|
|
|
|
@ -409,22 +403,19 @@ uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state()
|
|
|
|
logger.debug("%s Total buffer state - %d SDUs (%d B)", RB_NAME, n_sdus, n_bytes);
|
|
|
|
logger.debug("%s Total buffer state - %d SDUs (%d B)", RB_NAME, n_sdus, n_bytes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
return n_bytes;
|
|
|
|
return n_bytes;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int rlc_am_lte::rlc_am_lte_tx::write_sdu(unique_byte_buffer_t sdu)
|
|
|
|
int rlc_am_lte::rlc_am_lte_tx::write_sdu(unique_byte_buffer_t sdu)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
|
|
|
|
|
|
|
|
|
|
if (!tx_enabled) {
|
|
|
|
if (!tx_enabled) {
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (sdu.get() == nullptr) {
|
|
|
|
if (sdu.get() == nullptr) {
|
|
|
|
logger.warning("NULL SDU pointer in write_sdu()");
|
|
|
|
logger.warning("NULL SDU pointer in write_sdu()");
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -445,7 +436,6 @@ int rlc_am_lte::rlc_am_lte_tx::write_sdu(unique_byte_buffer_t sdu)
|
|
|
|
RB_NAME,
|
|
|
|
RB_NAME,
|
|
|
|
ret.error()->N_bytes,
|
|
|
|
ret.error()->N_bytes,
|
|
|
|
tx_sdu_queue.size());
|
|
|
|
tx_sdu_queue.size());
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -455,12 +445,10 @@ int rlc_am_lte::rlc_am_lte_tx::write_sdu(unique_byte_buffer_t sdu)
|
|
|
|
|
|
|
|
|
|
|
|
if (undelivered_sdu_info_queue.has_pdcp_sn(sdu_pdcp_sn)) {
|
|
|
|
if (undelivered_sdu_info_queue.has_pdcp_sn(sdu_pdcp_sn)) {
|
|
|
|
logger.error("PDCP SDU info already exists. SN=%d", sdu_pdcp_sn);
|
|
|
|
logger.error("PDCP SDU info already exists. SN=%d", sdu_pdcp_sn);
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
return SRSLTE_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
undelivered_sdu_info_queue.add_pdcp_sdu(sdu_pdcp_sn);
|
|
|
|
undelivered_sdu_info_queue.add_pdcp_sdu(sdu_pdcp_sn);
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
return SRSLTE_SUCCESS;
|
|
|
|
return SRSLTE_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -479,12 +467,10 @@ bool rlc_am_lte::rlc_am_lte_tx::sdu_queue_is_full()
|
|
|
|
|
|
|
|
|
|
|
|
int rlc_am_lte::rlc_am_lte_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes)
|
|
|
|
int rlc_am_lte::rlc_am_lte_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
|
|
|
|
|
|
|
|
|
|
int pdu_size = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (not tx_enabled) {
|
|
|
|
if (not tx_enabled) {
|
|
|
|
goto unlock_and_exit;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
logger.debug("MAC opportunity - %d bytes", nof_bytes);
|
|
|
|
logger.debug("MAC opportunity - %d bytes", nof_bytes);
|
|
|
@ -492,13 +478,12 @@ int rlc_am_lte::rlc_am_lte_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes)
|
|
|
|
|
|
|
|
|
|
|
|
if (not tx_enabled) {
|
|
|
|
if (not tx_enabled) {
|
|
|
|
logger.debug("RLC entity not active. Not generating PDU.");
|
|
|
|
logger.debug("RLC entity not active. Not generating PDU.");
|
|
|
|
goto unlock_and_exit;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Tx STATUS if requested
|
|
|
|
// Tx STATUS if requested
|
|
|
|
if (do_status() && not status_prohibit_timer.is_running()) {
|
|
|
|
if (do_status() && not status_prohibit_timer.is_running()) {
|
|
|
|
pdu_size = build_status_pdu(payload, nof_bytes);
|
|
|
|
return build_status_pdu(payload, nof_bytes);
|
|
|
|
goto unlock_and_exit;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Section 5.2.2.3 in TS 36.311, if tx_window is full and retx_queue empty, retransmit PDU
|
|
|
|
// Section 5.2.2.3 in TS 36.311, if tx_window is full and retx_queue empty, retransmit PDU
|
|
|
@ -508,23 +493,19 @@ int rlc_am_lte::rlc_am_lte_tx::read_pdu(uint8_t* payload, uint32_t nof_bytes)
|
|
|
|
|
|
|
|
|
|
|
|
// RETX if required
|
|
|
|
// RETX if required
|
|
|
|
if (not retx_queue.empty()) {
|
|
|
|
if (not retx_queue.empty()) {
|
|
|
|
pdu_size = build_retx_pdu(payload, nof_bytes);
|
|
|
|
int32_t pdu_size = build_retx_pdu(payload, nof_bytes);
|
|
|
|
if (pdu_size > 0) {
|
|
|
|
if (pdu_size > 0) {
|
|
|
|
goto unlock_and_exit;
|
|
|
|
return pdu_size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Build a PDU from SDUs
|
|
|
|
// Build a PDU from SDUs
|
|
|
|
pdu_size = build_data_pdu(payload, nof_bytes);
|
|
|
|
return build_data_pdu(payload, nof_bytes);
|
|
|
|
|
|
|
|
|
|
|
|
unlock_and_exit:
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
return pdu_size;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void rlc_am_lte::rlc_am_lte_tx::timer_expired(uint32_t timeout_id)
|
|
|
|
void rlc_am_lte::rlc_am_lte_tx::timer_expired(uint32_t timeout_id)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
std::unique_lock<std::mutex> lock(mutex);
|
|
|
|
if (poll_retx_timer.is_valid() && poll_retx_timer.id() == timeout_id) {
|
|
|
|
if (poll_retx_timer.is_valid() && poll_retx_timer.id() == timeout_id) {
|
|
|
|
logger.debug("%s Poll reTx timer expired after %dms", RB_NAME, poll_retx_timer.duration());
|
|
|
|
logger.debug("%s Poll reTx timer expired after %dms", RB_NAME, poll_retx_timer.duration());
|
|
|
|
// Section 5.2.2.3 in TS 36.311, schedule PDU for retransmission if
|
|
|
|
// Section 5.2.2.3 in TS 36.311, schedule PDU for retransmission if
|
|
|
@ -534,7 +515,8 @@ void rlc_am_lte::rlc_am_lte_tx::timer_expired(uint32_t timeout_id)
|
|
|
|
retransmit_pdu();
|
|
|
|
retransmit_pdu();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
|
|
|
|
lock.unlock();
|
|
|
|
|
|
|
|
|
|
|
|
if (bsr_callback) {
|
|
|
|
if (bsr_callback) {
|
|
|
|
bsr_callback(parent->lcid, get_buffer_state(), 0);
|
|
|
|
bsr_callback(parent->lcid, get_buffer_state(), 0);
|
|
|
@ -1091,7 +1073,7 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
std::unique_lock<std::mutex> lock(mutex);
|
|
|
|
|
|
|
|
|
|
|
|
logger.info(payload, nof_bytes, "%s Rx control PDU", RB_NAME);
|
|
|
|
logger.info(payload, nof_bytes, "%s Rx control PDU", RB_NAME);
|
|
|
|
|
|
|
|
|
|
|
@ -1196,7 +1178,7 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no
|
|
|
|
|
|
|
|
|
|
|
|
debug_state();
|
|
|
|
debug_state();
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
lock.unlock();
|
|
|
|
|
|
|
|
|
|
|
|
// Notify PDCP without holding Tx mutex
|
|
|
|
// Notify PDCP without holding Tx mutex
|
|
|
|
if (not notify_info_vec.empty()) {
|
|
|
|
if (not notify_info_vec.empty()) {
|
|
|
@ -1335,13 +1317,10 @@ rlc_am_lte::rlc_am_lte_rx::rlc_am_lte_rx(rlc_am_lte* parent_) :
|
|
|
|
pool(byte_buffer_pool::get_instance()),
|
|
|
|
pool(byte_buffer_pool::get_instance()),
|
|
|
|
logger(parent_->logger),
|
|
|
|
logger(parent_->logger),
|
|
|
|
reordering_timer(parent_->timers->get_unique_timer())
|
|
|
|
reordering_timer(parent_->timers->get_unique_timer())
|
|
|
|
{
|
|
|
|
{}
|
|
|
|
pthread_mutex_init(&mutex, NULL);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rlc_am_lte::rlc_am_lte_rx::~rlc_am_lte_rx()
|
|
|
|
rlc_am_lte::rlc_am_lte_rx::~rlc_am_lte_rx()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_mutex_destroy(&mutex);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool rlc_am_lte::rlc_am_lte_rx::configure(rlc_am_config_t cfg_)
|
|
|
|
bool rlc_am_lte::rlc_am_lte_rx::configure(rlc_am_config_t cfg_)
|
|
|
@ -1370,7 +1349,7 @@ void rlc_am_lte::rlc_am_lte_rx::reestablish()
|
|
|
|
|
|
|
|
|
|
|
|
void rlc_am_lte::rlc_am_lte_rx::stop()
|
|
|
|
void rlc_am_lte::rlc_am_lte_rx::stop()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
|
|
|
|
|
|
|
|
|
|
if (parent->timers != nullptr && reordering_timer.is_valid()) {
|
|
|
|
if (parent->timers != nullptr && reordering_timer.is_valid()) {
|
|
|
|
reordering_timer.stop();
|
|
|
|
reordering_timer.stop();
|
|
|
@ -1392,8 +1371,6 @@ void rlc_am_lte::rlc_am_lte_rx::stop()
|
|
|
|
|
|
|
|
|
|
|
|
// Drop all messages in RX window
|
|
|
|
// Drop all messages in RX window
|
|
|
|
rx_window.clear();
|
|
|
|
rx_window.clear();
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Called from stack thread when MAC has received a new RLC PDU
|
|
|
|
/** Called from stack thread when MAC has received a new RLC PDU
|
|
|
@ -1756,10 +1733,9 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus()
|
|
|
|
|
|
|
|
|
|
|
|
void rlc_am_lte::rlc_am_lte_rx::reset_status()
|
|
|
|
void rlc_am_lte::rlc_am_lte_rx::reset_status()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
|
|
do_status = false;
|
|
|
|
do_status = false;
|
|
|
|
poll_received = false;
|
|
|
|
poll_received = false;
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool rlc_am_lte::rlc_am_lte_rx::get_do_status()
|
|
|
|
bool rlc_am_lte::rlc_am_lte_rx::get_do_status()
|
|
|
@ -1772,19 +1748,16 @@ void rlc_am_lte::rlc_am_lte_rx::write_pdu(uint8_t* payload, const uint32_t nof_b
|
|
|
|
if (nof_bytes < 1) {
|
|
|
|
if (nof_bytes < 1) {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (rlc_am_is_control_pdu(payload)) {
|
|
|
|
if (rlc_am_is_control_pdu(payload)) {
|
|
|
|
// unlock mutex and pass to Tx subclass
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
parent->tx.handle_control_pdu(payload, nof_bytes);
|
|
|
|
parent->tx.handle_control_pdu(payload, nof_bytes);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
|
|
rlc_amd_pdu_header_t header = {};
|
|
|
|
rlc_amd_pdu_header_t header = {};
|
|
|
|
uint32_t payload_len = nof_bytes;
|
|
|
|
uint32_t payload_len = nof_bytes;
|
|
|
|
rlc_am_read_data_pdu_header(&payload, &payload_len, &header);
|
|
|
|
rlc_am_read_data_pdu_header(&payload, &payload_len, &header);
|
|
|
|
if (payload_len > nof_bytes) {
|
|
|
|
if (payload_len > nof_bytes) {
|
|
|
|
logger.info("Dropping corrupted PDU (%d B). Remaining length after header %d B.", nof_bytes, payload_len);
|
|
|
|
logger.info("Dropping corrupted PDU (%d B). Remaining length after header %d B.", nof_bytes, payload_len);
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (header.rf) {
|
|
|
|
if (header.rf) {
|
|
|
@ -1792,26 +1765,19 @@ void rlc_am_lte::rlc_am_lte_rx::write_pdu(uint8_t* payload, const uint32_t nof_b
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
handle_data_pdu(payload, payload_len, header);
|
|
|
|
handle_data_pdu(payload, payload_len, header);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t rlc_am_lte::rlc_am_lte_rx::get_rx_buffered_bytes()
|
|
|
|
uint32_t rlc_am_lte::rlc_am_lte_rx::get_rx_buffered_bytes()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint32_t buff_size = 0;
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
return rx_window.get_buffered_bytes();
|
|
|
|
buff_size = rx_window.get_buffered_bytes();
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
return buff_size;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t rlc_am_lte::rlc_am_lte_rx::get_sdu_rx_latency_ms()
|
|
|
|
uint32_t rlc_am_lte::rlc_am_lte_rx::get_sdu_rx_latency_ms()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint32_t latency = 0;
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
return sdu_rx_latency_ms.value();
|
|
|
|
latency = sdu_rx_latency_ms.value();
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
return latency;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -1821,7 +1787,7 @@ uint32_t rlc_am_lte::rlc_am_lte_rx::get_sdu_rx_latency_ms()
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
void rlc_am_lte::rlc_am_lte_rx::timer_expired(uint32_t timeout_id)
|
|
|
|
void rlc_am_lte::rlc_am_lte_rx::timer_expired(uint32_t timeout_id)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
|
|
if (reordering_timer.is_valid() and reordering_timer.id() == timeout_id) {
|
|
|
|
if (reordering_timer.is_valid() and reordering_timer.id() == timeout_id) {
|
|
|
|
logger.debug("%s reordering timeout expiry - updating vr_ms (was %d)", RB_NAME, vr_ms);
|
|
|
|
logger.debug("%s reordering timeout expiry - updating vr_ms (was %d)", RB_NAME, vr_ms);
|
|
|
|
|
|
|
|
|
|
|
@ -1842,13 +1808,12 @@ void rlc_am_lte::rlc_am_lte_rx::timer_expired(uint32_t timeout_id)
|
|
|
|
|
|
|
|
|
|
|
|
debug_state();
|
|
|
|
debug_state();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Called from Tx object to pack status PDU that doesn't exceed a given size
|
|
|
|
// Called from Tx object to pack status PDU that doesn't exceed a given size
|
|
|
|
int rlc_am_lte::rlc_am_lte_rx::get_status_pdu(rlc_status_pdu_t* status, const uint32_t max_pdu_size)
|
|
|
|
int rlc_am_lte::rlc_am_lte_rx::get_status_pdu(rlc_status_pdu_t* status, const uint32_t max_pdu_size)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
|
|
status->N_nack = 0;
|
|
|
|
status->N_nack = 0;
|
|
|
|
status->ack_sn = vr_r; // start with lower edge of the rx window
|
|
|
|
status->ack_sn = vr_r; // start with lower edge of the rx window
|
|
|
|
|
|
|
|
|
|
|
@ -1880,7 +1845,6 @@ int rlc_am_lte::rlc_am_lte_rx::get_status_pdu(rlc_status_pdu_t* status, const ui
|
|
|
|
rlc_am_packed_length(status),
|
|
|
|
rlc_am_packed_length(status),
|
|
|
|
max_pdu_size,
|
|
|
|
max_pdu_size,
|
|
|
|
status->N_nack);
|
|
|
|
status->N_nack);
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
@ -1888,14 +1852,13 @@ int rlc_am_lte::rlc_am_lte_rx::get_status_pdu(rlc_status_pdu_t* status, const ui
|
|
|
|
i = (i + 1) % MOD;
|
|
|
|
i = (i + 1) % MOD;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
return rlc_am_packed_length(status);
|
|
|
|
return rlc_am_packed_length(status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Called from Tx object to obtain length of the full status PDU
|
|
|
|
// Called from Tx object to obtain length of the full status PDU
|
|
|
|
int rlc_am_lte::rlc_am_lte_rx::get_status_pdu_length()
|
|
|
|
int rlc_am_lte::rlc_am_lte_rx::get_status_pdu_length()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
|
|
rlc_status_pdu_t status = {};
|
|
|
|
rlc_status_pdu_t status = {};
|
|
|
|
status.ack_sn = vr_ms;
|
|
|
|
status.ack_sn = vr_ms;
|
|
|
|
uint32_t i = vr_r;
|
|
|
|
uint32_t i = vr_r;
|
|
|
@ -1905,7 +1868,6 @@ int rlc_am_lte::rlc_am_lte_rx::get_status_pdu_length()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
i = (i + 1) % MOD;
|
|
|
|
i = (i + 1) % MOD;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pthread_mutex_unlock(&mutex);
|
|
|
|
|
|
|
|
return rlc_am_packed_length(&status);
|
|
|
|
return rlc_am_packed_length(&status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|