Merge branch 'next' into next_testers

This commit is contained in:
Ismael Gomez 2017-11-10 18:58:02 +01:00
commit 70062457d9
8 changed files with 100 additions and 34 deletions

View File

@ -123,8 +123,6 @@ public:
used.erase(elem);
available.push(b);
ret = true;
} else {
printf("Error deallocating from buffer pool: buffer not created in this pool.\n");
}
pthread_mutex_unlock(&mutex);
return ret;

View File

@ -46,6 +46,7 @@
#define HARQ_DELAY_MS 4
#define MSG3_DELAY_MS 2 // Delay added to HARQ_DELAY_MS
#define TTI_RX(tti) (tti>HARQ_DELAY_MS?((tti-HARQ_DELAY_MS)%10240):(10240+tti-HARQ_DELAY_MS))
#define TTI_TX(tti) ((tti+HARQ_DELAY_MS)%10240)
#define TTI_RX_ACK(tti) ((tti+(2*HARQ_DELAY_MS))%10240)

View File

@ -201,8 +201,14 @@ uint32_t rlc_am::get_total_buffer_state()
rlc_amd_retx_t retx = retx_queue.front();
log->debug("Buffer state - retx - SN: %d, Segment: %s, %d:%d\n", retx.sn, retx.is_segment ? "true" : "false", retx.so_start, retx.so_end);
if(tx_window.end() != tx_window.find(retx.sn)) {
n_bytes += required_buffer_size(retx);
int req_bytes = required_buffer_size(retx);
if (req_bytes < 0) {
log->error("In get_total_buffer_state(): Removing retx.sn=%d from queue\n", retx.sn);
retx_queue.pop_front();
} else {
n_bytes += req_bytes;
log->debug("Buffer state - retx: %d bytes\n", n_bytes);
}
}
}
@ -250,7 +256,13 @@ uint32_t rlc_am::get_buffer_state()
rlc_amd_retx_t retx = retx_queue.front();
log->debug("Buffer state - retx - SN: %d, Segment: %s, %d:%d\n", retx.sn, retx.is_segment ? "true" : "false", retx.so_start, retx.so_end);
if(tx_window.end() != tx_window.find(retx.sn)) {
n_bytes = required_buffer_size(retx);
int req_bytes = required_buffer_size(retx);
if (req_bytes < 0) {
log->error("In get_buffer_state(): Removing retx.sn=%d from queue\n", retx.sn);
retx_queue.pop_front();
goto unlock_and_return;
}
n_bytes = (uint32_t) req_bytes;
log->debug("Buffer state - retx: %d bytes\n", n_bytes);
goto unlock_and_return;
}
@ -296,8 +308,9 @@ int rlc_am::read_pdu(uint8_t *payload, uint32_t nof_bytes)
}
// RETX if required
if(retx_queue.size() > 0) {
int ret = build_retx_pdu(payload, nof_bytes);
pthread_mutex_unlock(&mutex);
return build_retx_pdu(payload, nof_bytes);
return ret;
}
// Build a PDU from SDUs
@ -438,16 +451,33 @@ int rlc_am::build_status_pdu(uint8_t *payload, uint32_t nof_bytes)
int rlc_am::build_retx_pdu(uint8_t *payload, uint32_t nof_bytes)
{
// Check there is at least 1 element before calling front()
if (retx_queue.empty()) {
log->error("In build_retx_pdu(): retx_queue is empty\n");
return -1;
}
rlc_amd_retx_t retx = retx_queue.front();
// Sanity check - drop any retx SNs not present in tx_window
while(tx_window.end() == tx_window.find(retx.sn)) {
retx_queue.pop_front();
retx = retx_queue.front();
if (!retx_queue.empty()) {
retx = retx_queue.front();
} else {
log->error("In build_retx_pdu(): retx_queue is empty during sanity check\n");
return -1;
}
}
// Is resegmentation needed?
if(retx.is_segment || required_buffer_size(retx) > (int)nof_bytes) {
int req_size = required_buffer_size(retx);
if (req_size < 0) {
log->error("In build_retx_pdu(): Removing retx.sn=%d from queue\n", retx.sn);
retx_queue.pop_front();
return -1;
}
if(retx.is_segment || req_size > (int)nof_bytes) {
log->debug("%s build_retx_pdu - resegmentation required\n", rrc->get_rb_name(lcid).c_str());
return build_segment(payload, nof_bytes, retx);
}
@ -481,6 +511,10 @@ int rlc_am::build_retx_pdu(uint8_t *payload, uint32_t nof_bytes)
int rlc_am::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_retx_t retx)
{
if (!tx_window[retx.sn].buf) {
log->error("In build_segment: retx.sn=%d has null buffer\n", retx.sn);
return 0;
}
if(!retx.is_segment){
retx.so_start = 0;
retx.so_end = tx_window[retx.sn].buf->N_bytes;
@ -1147,7 +1181,17 @@ bool rlc_am::add_segment_and_check(rlc_amd_rx_pdu_segments_t *pdu, rlc_amd_rx_pd
int rlc_am::required_buffer_size(rlc_amd_retx_t retx)
{
if(!retx.is_segment){
return rlc_am_packed_length(&tx_window[retx.sn].header) + tx_window[retx.sn].buf->N_bytes;
if (tx_window.count(retx.sn)) {
if (tx_window[retx.sn].buf) {
return rlc_am_packed_length(&tx_window[retx.sn].header) + tx_window[retx.sn].buf->N_bytes;
} else {
log->warning("retx.sn=%d has null ptr in required_buffer_size()\n", retx.sn);
return -1;
}
} else {
log->warning("retx.sn=%d does not exist in required_buffer_size()\n", retx.sn);
return -1;
}
}
// Construct new header

View File

@ -219,7 +219,7 @@ private:
// Receive and route HARQ feedbacks
if (grant) {
if ((!(grant->rnti_type == SRSLTE_RNTI_TEMP) && grant->ndi[0] != get_ndi()) ||
if ((!(grant->rnti_type == SRSLTE_RNTI_TEMP) && grant->ndi[0] != get_ndi() && grant->phy_grant.ul.mcs.idx < 29) ||
(grant->rnti_type == SRSLTE_RNTI_USER && !has_grant()) ||
grant->is_from_rar)
{
@ -245,7 +245,7 @@ private:
Warning("Uplink grant but no MAC PDU in Multiplex Unit buffer\n");
}
}
} else {
} else if (has_grant()) {
// Adaptive Re-TX
if (current_tx_nb >= max_retx) {
Info("UL %d: Maximum number of ReTX reached (%d). Discarting TB.\n", pid, max_retx);
@ -254,6 +254,8 @@ private:
} else {
generate_retx(tti_tx, grant, action);
}
} else {
Warning("UL %d: Received mcs=%d but no previous grant available for this PID.\n", pid, grant->phy_grant.ul.mcs.idx);
}
} else if (has_grant()) {
// Non-Adaptive Re-Tx

View File

@ -127,6 +127,8 @@ private:
// RRC constants and timers
srslte::mac_interface_timers *mac_timers;
uint32_t sync_reset_cnt;
const static uint32_t SYNC_RESET_TIMEOUT = 10;
uint32_t n310_cnt, N310;
uint32_t n311_cnt, N311;
uint32_t t301, t310, t311;

View File

@ -286,7 +286,7 @@ bool mux::sched_sdu(lchid_t *ch, int *sdu_space, int max_sdu_sz)
}
log_h->info("SDU: scheduled lcid=%d, rlc_buffer=%d, allocated=%d/%d\n",
ch->id, ch->buffer_len, sched_len, *sdu_space);
ch->id, ch->buffer_len, sched_len, sdu_space?*sdu_space:0);
*sdu_space -= sched_len;
ch->buffer_len -= sched_len;
@ -309,12 +309,11 @@ bool mux::allocate_sdu(uint32_t lcid, srslte::sch_pdu* pdu_msg, int max_sdu_sz)
sdu_len = max_sdu_sz;
}
int sdu_space = pdu_msg->get_sdu_space();
if (sdu_len > sdu_space) {
if (sdu_len > sdu_space || max_sdu_sz < 0) {
sdu_len = sdu_space;
}
}
if (sdu_len > MIN_RLC_SDU_LEN) {
if (pdu_msg->new_subh()) { // there is space for a new subheader
int sdu_len2 = sdu_len;
sdu_len = pdu_msg->get()->set_sdu(lcid, sdu_len, rlc);
if (sdu_len > 0) { // new SDU could be added

View File

@ -27,6 +27,7 @@
#include <unistd.h>
#include <string.h>
#include "phy/phch_worker.h"
#include "srslte/srslte.h"
#include "srslte/interfaces/ue_interfaces.h"
#include "srslte/asn1/liblte_rrc.h"
@ -40,8 +41,6 @@
#ifdef ENABLE_GUI
#include "srsgui/srsgui.h"
#include <semaphore.h>
#include "srslte/srslte.h"
#include "srslte/interfaces/ue_interfaces.h"
void init_plots(srsue::phch_worker *worker);
pthread_t plot_thread;
@ -323,9 +322,9 @@ void phch_worker::work_imp()
ul_action.tti_offset = HARQ_DELAY_MS;
/* Send UL grant or HARQ information (from PHICH) to MAC */
if (ul_grant_available && ul_ack_available) {
if (ul_grant_available && ul_ack_available && ul_mac_grant.phy_grant.ul.mcs.idx < 29) {
phy->mac->new_grant_ul_ack(ul_mac_grant, ul_ack, &ul_action);
} else if (ul_grant_available && !ul_ack_available) {
} else if (ul_grant_available && (!ul_ack_available || ul_mac_grant.phy_grant.ul.mcs.idx < 29)) {
phy->mac->new_grant_ul(ul_mac_grant, &ul_action);
} else if (!ul_grant_available && ul_ack_available) {
phy->mac->harq_recv(tti, ul_ack, &ul_action);
@ -480,11 +479,15 @@ bool phch_worker::decode_pdcch_dl(srsue::mac_interface_phy::mac_grant_t* grant)
grant->pid = ASYNC_DL_SCHED?dci_unpacked.harq_process:(tti%(2*HARQ_DELAY_MS));
// Set last TBS for this TB (pid) in case of mcs>29 (7.1.7.2 of 36.213)
// Set last TBS for this TB (pid) in case of mcs>28 (7.1.7.2 of 36.213)
for (int i=0;i<SRSLTE_MAX_CODEWORDS;i++) {
if (grant->phy_grant.dl.mcs[i].tbs < 0) {
if (grant->phy_grant.dl.mcs[i].idx > 28) {
grant->phy_grant.dl.mcs[i].tbs = last_dl_tbs[grant->pid%(2*HARQ_DELAY_MS)][i];
}
if(grant->phy_grant.dl.mcs[i].tbs < 0) {
Info("Invalid TBS size for PDSCH grant\n");
grant->phy_grant.dl.mcs[i].tbs = 0;
}
// save it
last_dl_tbs[grant->pid%(2*HARQ_DELAY_MS)][i] = grant->phy_grant.dl.mcs[i].tbs;
}
@ -539,10 +542,15 @@ int phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload[SRSL
}
}
uint32_t nof_tb = SRSLTE_RA_DL_GRANT_NOF_TB(grant);
switch(phy->config->dedicated.antenna_info_explicit_value.tx_mode) {
/* Implemented Tx Modes */
case LIBLTE_RRC_TRANSMISSION_MODE_1:
mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA;
if (nof_tb != 1) {
Error("Wrong number of transport blocks (%d) for single antenna.", nof_tb);
valid_config = false;
}
break;
case LIBLTE_RRC_TRANSMISSION_MODE_2:
if (cell.nof_ports > 1) {
@ -550,26 +558,30 @@ int phch_worker::decode_pdsch(srslte_ra_dl_grant_t *grant, uint8_t *payload[SRSL
} else {
mimo_type = SRSLTE_MIMO_TYPE_SINGLE_ANTENNA;
}
if (nof_tb != 1) {
Error("Wrong number of transport blocks (%d) for transmit diversity.", nof_tb);
valid_config = false;
}
break;
case LIBLTE_RRC_TRANSMISSION_MODE_3:
if (SRSLTE_RA_DL_GRANT_NOF_TB(grant) == 1) {
if (nof_tb == 1) {
mimo_type = SRSLTE_MIMO_TYPE_TX_DIVERSITY;
} else if (ue_dl.nof_rx_antennas > 1 && SRSLTE_RA_DL_GRANT_NOF_TB(grant) == 2) {
} else if (ue_dl.nof_rx_antennas > 1 && nof_tb == 2) {
mimo_type = SRSLTE_MIMO_TYPE_CDD;
} else {
Error("Wrong combination of antennas (%d) or transport blocks (%d) for TM3\n", ue_dl.nof_rx_antennas,
SRSLTE_RA_DL_GRANT_NOF_TB(grant));
nof_tb);
valid_config = false;
}
break;
case LIBLTE_RRC_TRANSMISSION_MODE_4:
if (SRSLTE_RA_DL_GRANT_NOF_TB(grant) == 1) {
if (nof_tb == 1) {
mimo_type = (grant->pinfo == 0) ? SRSLTE_MIMO_TYPE_TX_DIVERSITY : SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX;
} else if (ue_dl.nof_rx_antennas > 1 && SRSLTE_RA_DL_GRANT_NOF_TB(grant) == 2) {
} else if (ue_dl.nof_rx_antennas > 1 && nof_tb == 2) {
mimo_type = SRSLTE_MIMO_TYPE_SPATIAL_MULTIPLEX;
} else {
Error("Wrong combination of antennas (%d) or transport blocks (%d) for TM3\n", ue_dl.nof_rx_antennas,
SRSLTE_RA_DL_GRANT_NOF_TB(grant));
nof_tb);
valid_config = false;
}
break;
@ -734,16 +746,17 @@ bool phch_worker::decode_pdcch_ul(mac_interface_phy::mac_grant_t* grant)
if (ret) {
// Use last TBS for this TB in case of mcs>28
if (grant->phy_grant.ul.mcs.tbs < 0) {
grant->phy_grant.ul.mcs.tbs = last_ul_tbs[tti%(2*HARQ_DELAY_MS)];
if (grant->phy_grant.ul.mcs.idx > 28) {
grant->phy_grant.ul.mcs.tbs = last_ul_tbs[TTI_RX(tti)%(2*HARQ_DELAY_MS)];
Info("RETX: mcs=%d, old_tbs=%d pid=%d\n", grant->phy_grant.ul.mcs.idx, grant->phy_grant.ul.mcs.tbs, TTI_TX(tti)%(2*HARQ_DELAY_MS));
}
last_ul_tbs[tti%(2*HARQ_DELAY_MS)] = grant->phy_grant.ul.mcs.tbs;
last_ul_tbs[TTI_RX(tti)%(2*HARQ_DELAY_MS)] = grant->phy_grant.ul.mcs.tbs;
if (grant->phy_grant.ul.mcs.mod == SRSLTE_MOD_LAST) {
grant->phy_grant.ul.mcs.mod = last_ul_mod[tti%(2*HARQ_DELAY_MS)];
grant->phy_grant.ul.mcs.mod = last_ul_mod[TTI_RX(tti)%(2*HARQ_DELAY_MS)];
grant->phy_grant.ul.Qm = srslte_mod_bits_x_symbol(grant->phy_grant.ul.mcs.mod);
}
last_ul_mod[tti%(2*HARQ_DELAY_MS)] = grant->phy_grant.ul.mcs.mod;
last_ul_mod[TTI_RX(tti)%(2*HARQ_DELAY_MS)] = grant->phy_grant.ul.mcs.mod;
}
/* Limit UL modulation if not supported by the UE or disabled by higher layers */

View File

@ -48,6 +48,9 @@ rrc::rrc()
:state(RRC_STATE_IDLE)
,drb_up(false)
{
sync_reset_cnt = 0;
n310_cnt = 0;
n311_cnt = 0;
}
static void liblte_rrc_handler(void *ctx, char *str) {
@ -489,13 +492,17 @@ void rrc::earfcn_end() {
// Detection of physical layer problems (5.3.11.1)
void rrc::out_of_sync() {
// attempt resync
sync_reset_cnt++;
if (sync_reset_cnt >= SYNC_RESET_TIMEOUT) {
rrc_log->info("Detected %d out-of-sync from PHY. Resynchronizing PHY.\n", sync_reset_cnt);
phy->sync_reset();
sync_reset_cnt = 0;
}
current_cell->in_sync = false;
if (!mac_timers->timer_get(t311)->is_running() && !mac_timers->timer_get(t310)->is_running()) {
n310_cnt++;
if (n310_cnt == N310) {
// attempt resync
//phy->sync_reset();
mac_timers->timer_get(t310)->reset();
mac_timers->timer_get(t310)->run();
n310_cnt = 0;