Merge branch 'next' into next_mimo

master
Xavier Arteaga 7 years ago
commit 0947173fc1

@ -97,11 +97,13 @@ public:
bool running;
};
timers(uint32_t nof_timers_) : timer_list(nof_timers_) {
timers(uint32_t nof_timers_) : timer_list(nof_timers_),used_timers(nof_timers_) {
nof_timers = nof_timers_;
next_timer = 0;
nof_used_timers = 0;
for (uint32_t i=0;i<nof_timers;i++) {
timer_list[i].id = i;
used_timers[i] = false;
}
}
@ -133,17 +135,36 @@ public:
return NULL;
}
}
void release_id(uint32_t i) {
if (nof_used_timers > 0 && i < nof_timers) {
used_timers[i] = false;
nof_used_timers--;
} else {
fprintf(stderr, "Error releasing timer: nof_used_timers=%d, nof_timers=%d\n", nof_used_timers, nof_timers);
}
}
uint32_t get_unique_id() {
if (next_timer == nof_timers){
printf("No more unique timer ids (Only %d timers available)\n", nof_timers);
next_timer = 0;
if (nof_used_timers >= nof_timers) {
fprintf(stderr, "Error getting uinque timer id: no more timers available\n");
return 0;
} else {
while(used_timers[next_timer]) {
next_timer++;
if (next_timer >= nof_timers) {
next_timer=0;
}
}
used_timers[next_timer] = true;
nof_used_timers++;
return next_timer;
}
return next_timer++;
}
private:
uint32_t nof_timers;
uint32_t next_timer;
uint32_t nof_used_timers;
uint32_t nof_timers;
std::vector<timer> timer_list;
std::vector<bool> used_timers;
};
} // namespace srslte

@ -95,6 +95,7 @@ public:
int priority;
int bsd;
int pbr;
int group;
enum {IDLE = 0, UL, DL, BOTH} direction;
} ue_bearer_cfg_t;
@ -231,7 +232,7 @@ public:
/* UL information */
virtual int ul_crc_info(uint32_t tti, uint16_t rnti, bool crc) = 0;
virtual int ul_sr_info(uint32_t tti, uint16_t rnti) = 0;
virtual int ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr) = 0;
virtual int ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr, bool set_value = true) = 0;
virtual int ul_recv_len(uint16_t rnti, uint32_t lcid, uint32_t len) = 0;
virtual int ul_phr(uint16_t rnti, int phr) = 0;
virtual int ul_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi, uint32_t ul_ch_code) = 0;

@ -250,6 +250,9 @@ SRSLTE_API uint32_t srslte_N_ta_new_rar(uint32_t ta);
SRSLTE_API uint32_t srslte_N_ta_new(uint32_t N_ta_old,
uint32_t ta);
SRSLTE_API float srslte_coderate(uint32_t tbs,
uint32_t nof_re);
SRSLTE_API char *srslte_cp_string(srslte_cp_t cp);
SRSLTE_API srslte_mod_t srslte_str2mod (char * mod_str);

@ -96,9 +96,6 @@ SRSLTE_API int srslte_pdsch_set_rnti(srslte_pdsch_t *q,
SRSLTE_API void srslte_pdsch_free_rnti(srslte_pdsch_t *q,
uint16_t rnti);
SRSLTE_API float srslte_pdsch_coderate(uint32_t tbs,
uint32_t nof_re);
SRSLTE_API int srslte_pdsch_cfg(srslte_pdsch_cfg_t *cfg,
srslte_cell_t cell,
srslte_ra_dl_grant_t *grant,

@ -108,7 +108,6 @@ typedef struct SRSLTE_API {
bool group_hopping_en;
float threshold_format1;
float threshold_format1a;
float last_corr;
uint32_t last_n_prb;
uint32_t last_n_pucch;
@ -126,8 +125,7 @@ SRSLTE_API bool srslte_pucch_set_cfg(srslte_pucch_t* q,
bool group_hopping_en);
SRSLTE_API void srslte_pucch_set_threshold(srslte_pucch_t *q,
float format1,
float format1a);
float format1_threshold);
SRSLTE_API int srslte_pucch_set_crnti(srslte_pucch_t *q,
uint16_t c_rnti);

@ -152,6 +152,9 @@ SRSLTE_API void srslte_vec_conj_cc(cf_t *x, cf_t *y, uint32_t len);
/* average vector power */
SRSLTE_API float srslte_vec_avg_power_cf(cf_t *x, uint32_t len);
/* Correlation between complex vectors x and y */
SRSLTE_API float srslte_vec_corr_ccc(cf_t *x, cf_t *y, uint32_t len);
/* return the index of the maximum value in the vector */
SRSLTE_API uint32_t srslte_vec_max_fi(float *x, uint32_t len);
SRSLTE_API uint32_t srslte_vec_max_abs_ci(cf_t *x, uint32_t len);

@ -77,6 +77,7 @@ public:
// RRC interface
void reset();
void empty_queue();
void add_bearer(uint32_t lcid);
void add_bearer(uint32_t lcid, srslte_rlc_config_t cnfg);

@ -56,6 +56,7 @@ public:
void configure(srslte_rlc_config_t cnfg);
void reset();
void empty_queue();
bool active();
rlc_mode_t get_mode();

@ -33,7 +33,7 @@
// Table 6.1.3.1-1 Buffer size levels for BSR
static uint32_t btable[64] = {
0, 5, 10, 12, 14, 17, 19, 22, 26, 31, 36, 42, 49, 57, 67, 78, 91, 107, 125, 146, 171, 200, 234, 274, 321, 376, 440, 515, 603, 706, 826, 967, 1132,
0, 1, 10, 12, 14, 17, 19, 22, 26, 31, 36, 42, 49, 57, 67, 78, 91, 107, 125, 146, 171, 200, 234, 274, 321, 376, 440, 515, 603, 706, 826, 967, 1132,
1326, 1552, 1817, 2127, 2490, 2915, 3413, 3995, 4667, 5476, 6411, 7505, 8787, 10287, 12043, 14099, 16507, 19325, 22624, 26487, 31009, 36304,
42502, 49759, 58255, 68201, 79846, 93479, 109439, 128125, 150000};
@ -428,12 +428,16 @@ int sch_subh::get_bsr(uint32_t buff_size[4])
buff_size[2] = (payload[1]&0x0F) << 4 | (payload[1]&0xC0) >> 6;
buff_size[3] = (payload[2]&0x3F);
} else {
uint32_t nonzero_lcg = (payload[0]&0xc0) >> 6;
nonzero_lcg = (payload[0]&0xc0) >> 6;
buff_size[nonzero_lcg%4] = payload[0]&0x3f;
}
for (int i=0;i<4;i++) {
if (buff_size[i]) {
buff_size[i] = btable[buff_size[i]%64];
if (buff_size[i]<63) {
buff_size[i] = btable[1+buff_size[i]];
} else {
buff_size[i] = btable[63];
}
}
}
return nonzero_lcg;

@ -191,6 +191,11 @@ uint32_t srslte_N_ta_new(uint32_t N_ta_old, uint32_t ta) {
}
}
float srslte_coderate(uint32_t tbs, uint32_t nof_re)
{
return (float) (tbs + 24)/(nof_re);
}
/* Returns the new time advance as indicated by the random access response
* as specified in Section 4.2.3 of 36.213 */
uint32_t srslte_N_ta_new_rar(uint32_t ta) {

@ -91,7 +91,7 @@ int srslte_enb_ul_init(srslte_enb_ul_t *q, srslte_cell_t cell,
srslte_prach_set_detect_factor(&q->prach, 60);
}
srslte_pucch_set_threshold(&q->pucch, 0.5, 0.5);
srslte_pucch_set_threshold(&q->pucch, 0.8);
if (srslte_chest_ul_init(&q->chest, cell)) {
fprintf(stderr, "Error initiating channel estimator\n");

@ -57,11 +57,6 @@ extern int indices[100000];
extern int indices_ptr;
#endif
float srslte_pdsch_coderate(uint32_t tbs, uint32_t nof_re)
{
return (float) (tbs + 24)/(nof_re);
}
int srslte_pdsch_cp(srslte_pdsch_t *q, cf_t *input, cf_t *output, srslte_ra_dl_grant_t *grant, uint32_t lstart_grant, uint32_t nsubframe, bool put)
{
uint32_t s, n, l, lp, lstart, lend, nof_refs;

@ -411,9 +411,8 @@ static int pucch_get(srslte_pucch_t *q, srslte_pucch_format_t format, uint32_t n
return pucch_cp(q, format, n_pucch, input, z, true);
}
void srslte_pucch_set_threshold(srslte_pucch_t *q, float format1, float format1a) {
q->threshold_format1 = format1;
q->threshold_format1a = format1a;
void srslte_pucch_set_threshold(srslte_pucch_t *q, float format1_threshold) {
q->threshold_format1 = format1_threshold;
}
/** Initializes the PDCCH transmitter and receiver */
@ -452,6 +451,8 @@ int srslte_pucch_init(srslte_pucch_t *q, srslte_cell_t cell) {
q->z_tmp = srslte_vec_malloc(sizeof(cf_t)*SRSLTE_PUCCH_MAX_SYMBOLS);
q->ce = srslte_vec_malloc(sizeof(cf_t)*SRSLTE_PUCCH_MAX_SYMBOLS);
q->threshold_format1 = 0.8;
ret = SRSLTE_SUCCESS;
}
return ret;
@ -612,6 +613,10 @@ static int uci_mod_bits(srslte_pucch_t *q, srslte_pucch_format_t format, uint8_t
// Declare this here, since we can not include refsignal_ul.h
void srslte_refsignal_r_uv_arg_1prb(float *arg, uint32_t u);
float tmp_alpha;
uint32_t tmp_noc, tmp_nprime, tmp_woc;
static int pucch_encode_(srslte_pucch_t* q, srslte_pucch_format_t format,
uint32_t n_pucch, uint32_t sf_idx, uint16_t rnti,
uint8_t bits[SRSLTE_PUCCH_MAX_BITS], cf_t z[SRSLTE_PUCCH_MAX_SYMBOLS], bool signal_only)
@ -657,6 +662,12 @@ static int pucch_encode_(srslte_pucch_t* q, srslte_pucch_format_t format,
}
DEBUG("PUCCH d_0: %.1f+%.1fi, alpha: %.1f, n_oc: %d, n_prime_ns: %d, n_rb_2=%d\n",
__real__ q->d[0], __imag__ q->d[0], alpha, n_oc, n_prime_ns, q->pucch_cfg.n_rb_2);
tmp_alpha = alpha;
tmp_noc = n_oc;
tmp_nprime = n_prime_ns;
tmp_woc = w_n_oc[N_sf_widx][n_oc%3][m];
for (uint32_t n=0;n<SRSLTE_PUCCH_N_SEQ;n++) {
z[(ns%2)*N_sf_0*SRSLTE_PUCCH_N_SEQ+m*SRSLTE_PUCCH_N_SEQ+n] =
q->d[0]*cexpf(I*(w_n_oc[N_sf_widx][n_oc%3][m]+q->tmp_arg[n]+alpha*n+S_ns));
@ -767,7 +778,7 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format,
case SRSLTE_PUCCH_FORMAT_1:
bzero(bits, SRSLTE_PUCCH_MAX_BITS*sizeof(uint8_t));
pucch_encode(q, format, n_pucch, sf_idx, rnti, bits, q->z_tmp);
corr = crealf(srslte_vec_dot_prod_conj_ccc(q->z, q->z_tmp, nof_re))/nof_re;
corr = srslte_vec_corr_ccc(q->z, q->z_tmp, nof_re);
if (corr >= q->threshold_format1) {
ret = 1;
} else {
@ -782,7 +793,7 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format,
for (int b=0;b<2;b++) {
bits[0] = b;
pucch_encode(q, format, n_pucch, sf_idx, rnti, bits, q->z_tmp);
corr = crealf(srslte_vec_dot_prod_conj_ccc(q->z, q->z_tmp, nof_re))/nof_re;
corr = srslte_vec_corr_ccc(q->z, q->z_tmp, nof_re);
if (corr > corr_max) {
corr_max = corr;
b_max = b;
@ -790,7 +801,7 @@ int srslte_pucch_decode(srslte_pucch_t* q, srslte_pucch_format_t format,
if (corr_max > q->threshold_format1) { // check with format1 in case ack+sr because ack only is binary
ret = 1;
}
DEBUG("format1a b=%d, corr=%f, nof_re=%d, th=%f\n", b, corr, nof_re, q->threshold_format1a);
DEBUG("format1a b=%d, corr=%f, nof_re=%d\n", b, corr, nof_re);
}
q->last_corr = corr_max;
bits[0] = b_max;

@ -328,7 +328,7 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels)
if (args[0]=='\0') {
if (find_string(devices_str, "type=b200") && !strstr(args, "recv_frame_size")) {
// If B200 is available, use it
args = "type=b200";
args = "type=b200,master_clock_rate=30.72e6";
handler->devname = DEVNAME_B200;
} else if (find_string(devices_str, "type=x300")) {
// Else if X300 is available, set master clock rate now (can't be changed later)
@ -344,6 +344,8 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels)
handler->dynamic_rate = false;
handler->devname = DEVNAME_X300;
} else if (strstr(args, "type=b200")) {
snprintf(args2, sizeof(args2), "%s,master_clock_rate=30.72e6", args);
args = args2;
handler->devname = DEVNAME_B200;
}
}
@ -400,6 +402,11 @@ int rf_uhd_open_multi(char *args, void **h, uint32_t nof_channels)
handler->nof_rx_channels = nof_channels;
handler->nof_tx_channels = nof_channels;
/* Set default rate to avoid decimation warnings */
uhd_usrp_set_rx_rate(handler->usrp, 1.92e6, 0);
uhd_usrp_set_tx_rate(handler->usrp, 1.92e6, 0);
/* Initialize rx and tx stremers */
uhd_rx_streamer_make(&handler->rx_stream);
error = uhd_usrp_get_rx_stream(handler->usrp, &stream_args, handler->rx_stream);

@ -681,6 +681,15 @@ float srslte_vec_avg_power_cf(cf_t *x, uint32_t len) {
return crealf(srslte_vec_dot_prod_conj_ccc(x,x,len)) / len;
}
// Correlation assumes zero-mean x and y
float srslte_vec_corr_ccc(cf_t *x, cf_t *y, uint32_t len) {
// return crealf(srslte_vec_dot_prod_conj_ccc(x,y,len)) / len;
float s_x = crealf(srslte_vec_dot_prod_conj_ccc(x, x, len))/len;
float s_y = crealf(srslte_vec_dot_prod_conj_ccc(y, y, len))/len;
float cov = crealf(srslte_vec_dot_prod_conj_ccc(x, y, len))/len;
return cov/(sqrt(s_x*s_y));
}
void srslte_vec_abs_cf(cf_t *x, float *abs, uint32_t len) {
#ifndef HAVE_VOLK_MAG_FUNCTION
int i;

@ -336,7 +336,7 @@ void radio::set_tx_srate(float srate)
} else if (srate_khz == 15.36e3) {
nsamples = 131;
} else if (srate_khz == 23.04e3) {
nsamples = 175;
nsamples = 150;
} else {
/* Interpolate from known values */
printf("\nWarning TX/RX time offset for sampling rate %.0f KHz not calibrated. Using interpolated value\n\n", cur_tx_srate);
@ -356,7 +356,7 @@ void radio::set_tx_srate(float srate)
} else if (srate_khz == 15.36e3) {
nsamples = 86;
} else if (srate_khz == 23.04e3) {
nsamples = 119;
nsamples = 110;
} else {
/* Interpolate from known values */
printf("\nWarning TX/RX time offset for sampling rate %.0f KHz not calibrated. Using interpolated value\n\n", cur_tx_srate);

@ -102,6 +102,14 @@ void rlc::reset()
rlc_array[0].init(RLC_MODE_TM, rlc_log, default_lcid, pdcp, rrc, mac_timers); // SRB0
}
void rlc::empty_queue()
{
for(uint32_t i=0; i<SRSLTE_N_RADIO_BEARERS; i++) {
if(rlc_array[i].active())
rlc_array[i].empty_queue();
}
}
/*******************************************************************************
PDCP interface
*******************************************************************************/

@ -76,6 +76,12 @@ void rlc_entity::reset()
rlc = NULL;
}
void rlc_entity::empty_queue()
{
rlc->empty_queue();
}
bool rlc_entity::active()
{
return (rlc != NULL);

@ -15,14 +15,14 @@ qci_config = (
};
dl_um = {
sn_field_length = 10;
t_reordering = 80;
t_reordering = 45;
};
};
logical_channel_config = {
priority = 11;
priority = 13;
prioritized_bit_rate = -1;
bucket_size_duration = 100;
log_chan_group = 3;
log_chan_group = 2;
};
},
{

@ -57,8 +57,8 @@ drb_config = drb.conf
#####################################################################
[rf]
dl_earfcn = 3400
tx_gain = 70
rx_gain = 50
tx_gain = 80
rx_gain = 60
#device_name = auto
#device_args = auto
@ -121,7 +121,7 @@ enable = false
#pdsch_mcs = -1
#pdsch_max_mcs = -1
#pusch_mcs = -1
pusch_max_mcs = 16
#pusch_max_mcs = -1
nof_ctrl_symbols = 2
#####################################################################
@ -141,9 +141,9 @@ nof_ctrl_symbols = 2
#pdsch_max_its = 4
#nof_phy_threads = 2
#pregenerate_signals = false
#tx_amplitude = 0.8
#tx_amplitude = 0.6
#link_failure_nof_err = 50
#rrc_inactivity_timer = 30000
#rrc_inactivity_timer = 10000
#max_prach_offset_us = 30
#####################################################################

@ -108,7 +108,7 @@ public:
int ul_crc_info(uint32_t tti, uint16_t rnti, bool crc);
int ul_sr_info(uint32_t tti, uint16_t rnti);
int ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr);
int ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr, bool set_value = true);
int ul_recv_len(uint16_t rnti, uint32_t lcid, uint32_t len);
int ul_phr(uint16_t rnti, int phr);
int ul_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi, uint32_t ul_ch_code);

@ -105,6 +105,7 @@ public:
void same_alloc();
bool is_adaptive_retx();
void reset_pending_data();
bool has_pending_ack();
uint32_t get_pending_data();

@ -62,7 +62,7 @@ public:
void rem_bearer(uint32_t lc_id);
void dl_buffer_state(uint8_t lc_id, uint32_t tx_queue, uint32_t retx_queue);
void ul_buffer_state(uint8_t lc_id, uint32_t bsr);
void ul_buffer_state(uint8_t lc_id, uint32_t bsr, bool set_value = true);
void ul_phr(int phr);
void mac_buffer_state(uint32_t ce_code);
void ul_recv_len(uint32_t lcid, uint32_t len);
@ -116,6 +116,8 @@ public:
bool get_pucch_sched(uint32_t current_tti, uint32_t prb_idx[2], uint32_t *L);
bool pucch_sr_collision(uint32_t current_tti, uint32_t n_cce);
uint32_t get_pending_ul_old_data();
private:
typedef struct {
@ -126,12 +128,13 @@ private:
} ue_bearer_t;
bool is_sr_triggered();
uint32_t get_pending_ul_old_data();
int alloc_pdu(int tbs, sched_interface::dl_sched_pdu_t* pdu);
static uint32_t format1_count_prb(uint32_t bitmask, uint32_t cell_nof_prb);
static int cqi_to_tbs(uint32_t cqi, uint32_t nof_prb, uint32_t nof_re, uint32_t max_mcs, uint32_t *mcs);
static int alloc_tbs(uint32_t cqi, uint32_t nof_prb, uint32_t nof_re, uint32_t req_bytes, uint32_t max_mcs, int *mcs);
static int cqi_to_tbs(uint32_t cqi, uint32_t nof_prb, uint32_t nof_re, uint32_t max_mcs, uint32_t max_Qm, uint32_t *mcs);
int alloc_tbs_dl(uint32_t nof_prb, uint32_t nof_re, uint32_t req_bytes, int *mcs);
int alloc_tbs_ul(uint32_t nof_prb, uint32_t nof_re, uint32_t req_bytes, int *mcs);
int alloc_tbs(uint32_t nof_prb, uint32_t nof_re, uint32_t req_bytes, bool is_ul, int *mcs);
static bool bearer_is_ul(ue_bearer_t *lch);
static bool bearer_is_dl(ue_bearer_t *lch);

@ -58,6 +58,10 @@ public:
}
virtual ~ue() {
for (int i=0;i<NOF_HARQ_PROCESSES;i++) {
srslte_softbuffer_rx_free(&softbuffer_rx[i]);
srslte_softbuffer_tx_free(&softbuffer_tx[i]);
}
pthread_mutex_destroy(&mutex);
}
@ -82,6 +86,8 @@ public:
uint32_t rl_failure();
void rl_failure_reset();
void set_lcg(uint32_t lcid, uint32_t lcg);
void metrics_read(srsenb::mac_metrics_t* metrics);
void metrics_rx(bool crc, uint32_t tbs);
void metrics_tx(bool crc, uint32_t tbs);
@ -98,6 +104,8 @@ private:
void metrics_phr(float phr);
uint32_t phr_counter;
std::vector<uint32_t> lc_groups[4];
mac_metrics_t metrics;
srslte::mac_pcap* pcap;

@ -9,7 +9,7 @@ mac_cnfg =
ulsch_cnfg =
{
max_harq_tx = 4;
periodic_bsr_timer = 5; // in ms
periodic_bsr_timer = 40; // in ms
retx_bsr_timer = 320; // in ms
};
@ -28,7 +28,7 @@ phy_cnfg =
{
beta_offset_ack_idx = 10;
beta_offset_ri_idx = 5;
beta_offset_cqi_idx = 5;
beta_offset_cqi_idx = 10;
};
// PUCCH-SR resources are scheduled on time-frequeny domain first, then multiplexed in the same resource.

@ -23,9 +23,9 @@ sib2 =
rach_cnfg =
{
num_ra_preambles = 52;
preamble_init_rx_target_pwr = -108;
preamble_init_rx_target_pwr = -104;
pwr_ramping_step = 6; // in dB
preamble_trans_max = 7;
preamble_trans_max = 10;
ra_resp_win_size = 10; // in ms
mac_con_res_timer = 64; // in ms
max_harq_msg3_tx = 4;
@ -53,14 +53,14 @@ sib2 =
pdsch_cnfg =
{
p_b = 0;
rs_power = -4;
rs_power = 20;
};
pusch_cnfg =
{
n_sb = 1;
hopping_mode = "inter-subframe";
pusch_hopping_offset = 2;
enable_64_qam = false;
enable_64_qam = false; // 64QAM PUSCH is not currently enabled
ul_rs =
{
cyclic_shift = 0;
@ -71,25 +71,25 @@ sib2 =
};
pucch_cnfg =
{
delta_pucch_shift = 1;
n_rb_cqi = 1;
delta_pucch_shift = 2;
n_rb_cqi = 2;
n_cs_an = 0;
n1_pucch_an = 2;
n1_pucch_an = 12;
};
ul_pwr_ctrl =
{
p0_nominal_pusch = -108;
alpha = 1.0;
p0_nominal_pucch = -88;
p0_nominal_pusch = -85;
alpha = 0.7;
p0_nominal_pucch = -107;
delta_flist_pucch =
{
format_1 = 2;
format_1 = 0;
format_1b = 3;
format_2 = 0;
format_2a = 0;
format_2b = 0;
format_2 = 1;
format_2a = 2;
format_2b = 2;
};
delta_preamble_msg3 = 4;
delta_preamble_msg3 = 8;
};
ul_cp_length = "Normal";
};

@ -33,6 +33,7 @@
#include <strings.h>
#include <pthread.h>
#include <unistd.h>
#include <srslte/interfaces/sched_interface.h>
#include "srslte/common/log.h"
#include "mac/mac.h"
@ -164,6 +165,8 @@ int mac::rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint
int mac::bearer_ue_cfg(uint16_t rnti, uint32_t lc_id, sched_interface::ue_bearer_cfg_t* cfg)
{
if (ue_db.count(rnti)) {
// configure BSR group in UE
ue_db[rnti]->set_lcg(lc_id, (uint32_t) cfg->group);
return scheduler.bearer_ue_cfg(rnti, lc_id, cfg);
} else {
Error("User rnti=0x%x not found\n", rnti);
@ -259,7 +262,7 @@ void mac::rl_failure(uint16_t rnti)
if (ue_db.count(rnti)) {
uint32_t nof_fails = ue_db[rnti]->rl_failure();
if (nof_fails >= (uint32_t) args.link_failure_nof_err && args.link_failure_nof_err > 0) {
Info("Detected PUSCH failure for rnti=0x%x\n", rnti);
Info("Detected Uplink failure for rnti=0x%x\n", rnti);
rrc_h->rl_failure(rnti);
ue_db[rnti]->rl_failure_reset();
}

@ -302,12 +302,12 @@ int sched::ul_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cqi, uint32_t ul_ch
return ret;
}
int sched::ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr)
int sched::ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr, bool set_value)
{
pthread_mutex_lock(&mutex);
int ret = 0;
if (ue_db.count(rnti)) {
ue_db[rnti].ul_buffer_state(lcid, bsr);
ue_db[rnti].ul_buffer_state(lcid, bsr, set_value);
} else {
Error("User rnti=0x%x not found\n", rnti);
ret = -1;
@ -792,13 +792,13 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched
user->unset_sr();
}
log_h->info("SCHED: %s %s rnti=0x%x, pid=%d, dci=%d,%d, grant=%d,%d, n_rtx=%d, tbs=%d, bsr=%d (%d)\n",
log_h->info("SCHED: %s %s rnti=0x%x, pid=%d, dci=%d,%d, grant=%d,%d, n_rtx=%d, tbs=%d, bsr=%d (%d-%d)\n",
is_rar?"RAR":"UL",
is_newtx?"tx":"retx",
rnti, h->get_id(),
sched_result->pusch[nof_dci_elems].dci_location.L, sched_result->pusch[nof_dci_elems].dci_location.ncce,
alloc.RB_start, alloc.L, h->nof_retx(), sched_result->pusch[nof_dci_elems].tbs,
user->get_pending_ul_new_data(current_tti),pending_data_before);
user->get_pending_ul_new_data(current_tti),pending_data_before, user->get_pending_ul_old_data());
nof_dci_elems++;
} else {
@ -814,6 +814,14 @@ int sched::ul_sched(uint32_t tti, srsenb::sched_interface::ul_sched_res_t* sched
}
}
// Update pending data counters after this TTI
for(std::map<uint16_t, sched_ue>::iterator iter=ue_db.begin(); iter!=ue_db.end(); ++iter) {
sched_ue *user = (sched_ue *) &iter->second;
uint16_t rnti = (uint16_t) iter->first;
user->get_ul_harq(current_tti)->reset_pending_data();
}
sched_result->nof_dci_elems = nof_dci_elems;
sched_result->nof_phich_elems = nof_phich_elems;

@ -229,13 +229,22 @@ bool ul_harq_proc::has_pending_ack()
active = false;
}
if (!active) {
pending_data = 0;
need_ack = false;
}
return ret;
}
uint32_t ul_harq_proc::get_pending_data()
void ul_harq_proc::reset_pending_data()
{
if (!active) {
pending_data = 0;
}
}
uint32_t ul_harq_proc::get_pending_data()
{
return pending_data;
}

@ -26,6 +26,8 @@
#include <string.h>
#include <boost/concept_check.hpp>
#include <srslte/interfaces/sched_interface.h>
#include <srslte/phy/phch/pucch.h>
#include "srslte/srslte.h"
#include "srslte/common/pdu.h"
@ -163,12 +165,17 @@ void sched_ue::phy_config_enabled(uint32_t tti, bool enabled)
phy_config_dedicated_enabled = enabled;
}
void sched_ue::ul_buffer_state(uint8_t lc_id, uint32_t bsr)
void sched_ue::ul_buffer_state(uint8_t lc_id, uint32_t bsr, bool set_value)
{
if (lc_id < sched_interface::MAX_LC) {
if (set_value) {
lch[lc_id].bsr = bsr;
Debug("SCHED: UL lcid=%d buffer_state=%d\n", lc_id, bsr);
} else {
lch[lc_id].bsr += bsr;
}
}
Debug("SCHED: bsr=%d, lcid=%d, bsr={%d,%d,%d,%d}\n", bsr, lc_id,
lch[0].bsr, lch[1].bsr, lch[2].bsr, lch[3].bsr);
}
void sched_ue::ul_phr(int phr)
@ -231,6 +238,7 @@ bool sched_ue::get_pucch_sched(uint32_t current_tti, uint32_t prb_idx[2], uint32
return false;
}
srslte_pucch_sched_t pucch_sched;
pucch_sched.sps_enabled = false;
pucch_sched.n_pucch_sr = cfg.sr_N_pucch;
pucch_sched.n_pucch_2 = cfg.n_pucch_cqi;
pucch_sched.N_pucch_1 = cfg.pucch_cfg.n1_pucch_an;
@ -239,7 +247,7 @@ bool sched_ue::get_pucch_sched(uint32_t current_tti, uint32_t prb_idx[2], uint32
// First check if it has pending ACKs
for (int i=0;i<SCHED_MAX_HARQ_PROC;i++) {
if (((dl_harq[i].get_tti()+8)%10240) == current_tti) {
if (((dl_harq[i].get_tti()+4)%10240) == current_tti) {
uint32_t n_pucch = srslte_pucch_get_npucch(dl_harq[i].get_n_cce(), SRSLTE_PUCCH_FORMAT_1A, has_sr, &pucch_sched);
if (prb_idx) {
for (int i=0;i<2;i++) {
@ -249,7 +257,7 @@ bool sched_ue::get_pucch_sched(uint32_t current_tti, uint32_t prb_idx[2], uint32
if (L) {
*L = 1;
}
Debug("SCHED: Reserved Format1A PUCCH for rnti=0x%x, n_prb=%d,%d, n_pucch=%d\n", rnti, prb_idx[0], prb_idx[1], n_pucch);
Info("SCHED: Reserved Format1A PUCCH for rnti=0x%x, n_prb=%d,%d, n_pucch=%d\n", rnti, prb_idx[0], prb_idx[1], n_pucch);
return true;
}
}
@ -263,9 +271,24 @@ bool sched_ue::get_pucch_sched(uint32_t current_tti, uint32_t prb_idx[2], uint32
if (L) {
*L = 1;
}
Debug("SCHED: Reserved Format1 PUCCH for rnti=0x%x, n_prb=%d,%d, n_pucch=%d\n", rnti, prb_idx[0], prb_idx[1], cfg.sr_N_pucch);
Info("SCHED: Reserved Format1 PUCCH for rnti=0x%x, n_prb=%d,%d, n_pucch=%d\n", rnti, prb_idx[0], prb_idx[1], cfg.sr_N_pucch);
return true;
}
// Finally check Format2 (periodic CQI)
if (cfg.cqi_enabled && srslte_cqi_send(cfg.cqi_idx, current_tti)) {
if (prb_idx) {
for (int i=0;i<2;i++) {
prb_idx[i] = srslte_pucch_n_prb(&cfg.pucch_cfg, SRSLTE_PUCCH_FORMAT_2, cfg.cqi_pucch, cell.nof_prb, cell.cp, i);
}
}
if(L) {
*L = 2;
}
Info("SCHED: Reserved Format2 PUCCH for rnti=0x%x, n_prb=%d,%d, n_pucch=%d, pmi_idx=%d\n",
rnti, prb_idx[0], prb_idx[1], cfg.cqi_pucch, cfg.cqi_idx);
return true;
}
return false;
}
@ -297,6 +320,8 @@ void sched_ue::ul_recv_len(uint32_t lcid, uint32_t len)
}
}
}
Debug("SCHED: recv_len=%d, lcid=%d, bsr={%d,%d,%d,%d}\n", len, lcid,
lch[0].bsr, lch[1].bsr, lch[2].bsr, lch[3].bsr);
}
void sched_ue::set_ul_crc(uint32_t tti, bool crc_res)
@ -370,7 +395,7 @@ int sched_ue::generate_format1(dl_harq_proc *h,
uint32_t nof_ctrl_symbols = cfi+(cell.nof_prb<10?1:0);
uint32_t nof_re = srslte_ra_dl_grant_nof_re(&grant, cell, sf_idx, nof_ctrl_symbols);
if (fixed_mcs_dl < 0) {
tbs = alloc_tbs(dl_cqi, nof_prb, nof_re, req_bytes, max_mcs_dl, &mcs);
tbs = alloc_tbs_dl(nof_prb, nof_re, req_bytes, &mcs);
} else {
tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(fixed_mcs_dl), nof_prb);
mcs = fixed_mcs_dl;
@ -441,7 +466,7 @@ int sched_ue::generate_format0(ul_harq_proc *h,
uint32_t N_srs = 0;
uint32_t nof_re = (2*(SRSLTE_CP_NSYMB(cell.cp)-1) - N_srs)*allocation.L*SRSLTE_NRE;
if (fixed_mcs_ul < 0) {
tbs = alloc_tbs(ul_cqi, allocation.L, nof_re, req_bytes, max_mcs_ul, &mcs);
tbs = alloc_tbs_ul(allocation.L, nof_re, req_bytes, &mcs);
} else {
tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(fixed_mcs_ul), allocation.L);
mcs = fixed_mcs_ul;
@ -554,6 +579,10 @@ uint32_t sched_ue::get_pending_ul_new_data(uint32_t tti)
} else {
pending_data = 0;
}
if (pending_data) {
Debug("SCHED: pending_data=%d, pending_ul_data=%d, bsr={%d,%d,%d,%d}\n", pending_data,pending_ul_data,
lch[0].bsr, lch[1].bsr, lch[2].bsr, lch[3].bsr);
}
return pending_data;
}
@ -581,7 +610,7 @@ uint32_t sched_ue::get_required_prb_dl(uint32_t req_bytes, uint32_t nof_ctrl_sym
for (n=1;n<cell.nof_prb && nbytes < req_bytes;n++) {
nof_re = srslte_ra_dl_approx_nof_re(cell, n, nof_ctrl_symbols);
if (fixed_mcs_dl < 0) {
tbs = alloc_tbs(dl_cqi, n, nof_re, 0, max_mcs_dl, &mcs);
tbs = alloc_tbs_dl(n, nof_re, 0, &mcs);
} else {
tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(fixed_mcs_dl), n);
}
@ -610,7 +639,7 @@ uint32_t sched_ue::get_required_prb_ul(uint32_t req_bytes)
uint32_t nof_re = (2*(SRSLTE_CP_NSYMB(cell.cp)-1) - N_srs)*n*SRSLTE_NRE;
int tbs = 0;
if (fixed_mcs_ul < 0) {
tbs = alloc_tbs(ul_cqi, n, nof_re, 0, max_mcs_ul, &mcs);
tbs = alloc_tbs_ul(n, nof_re, 0, &mcs);
} else {
tbs = srslte_ra_tbs_from_idx(srslte_ra_tbs_idx_from_mcs(fixed_mcs_ul), n);
}
@ -731,36 +760,60 @@ uint32_t sched_ue::format1_count_prb(uint32_t bitmask, uint32_t cell_nof_prb) {
return nof_prb;
}
int sched_ue::cqi_to_tbs(uint32_t cqi, uint32_t nof_prb, uint32_t nof_re, uint32_t max_mcs, uint32_t *mcs) {
int sched_ue::cqi_to_tbs(uint32_t cqi, uint32_t nof_prb, uint32_t nof_re, uint32_t max_mcs, uint32_t max_Qm, uint32_t *mcs) {
float max_coderate = srslte_cqi_to_coderate(cqi);
int sel_mcs = max_mcs+1;
float coderate = 99;
float eff_coderate = 99;
uint32_t Qm = 1;
int tbs = 0;
do {
sel_mcs--;
uint32_t tbs_idx = srslte_ra_tbs_idx_from_mcs(sel_mcs);
tbs = srslte_ra_tbs_from_idx(tbs_idx, nof_prb);
coderate = srslte_pdsch_coderate(tbs, nof_re);
} while(sel_mcs > 0 && coderate >= max_coderate);
coderate = srslte_coderate(tbs, nof_re);
Qm = SRSLTE_MIN(max_Qm, srslte_mod_bits_x_symbol(srslte_ra_mod_from_mcs(sel_mcs)));
eff_coderate = coderate/Qm;
} while((sel_mcs > 0 && coderate > max_coderate) || eff_coderate > 0.930);
if (mcs) {
*mcs = (uint32_t) sel_mcs;
}
return tbs;
}
/* In this scheduler we tend to use all the available bandwidth and select the MCS
int sched_ue::alloc_tbs_dl(uint32_t nof_prb,
uint32_t nof_re,
uint32_t req_bytes,
int *mcs)
{
return alloc_tbs(nof_prb, nof_re, req_bytes, false, mcs);
}
int sched_ue::alloc_tbs_ul(uint32_t nof_prb,
uint32_t nof_re,
uint32_t req_bytes,
int *mcs)
{
return alloc_tbs(nof_prb, nof_re, req_bytes, true, mcs);
}
/* In this scheduler we tend to use all the available bandwidth and select the MCS
* that approximates the minimum between the capacity and the requested rate
*/
int sched_ue::alloc_tbs(uint32_t cqi,
uint32_t nof_prb,
int sched_ue::alloc_tbs(uint32_t nof_prb,
uint32_t nof_re,
uint32_t req_bytes,
uint32_t max_mcs,
bool is_ul,
int *mcs)
{
uint32_t sel_mcs = 0;
int tbs = cqi_to_tbs(cqi, nof_prb, nof_re, max_mcs, &sel_mcs)/8;
uint32_t cqi = is_ul?ul_cqi:dl_cqi;
uint32_t max_mcs = is_ul?max_mcs_ul:max_mcs_dl;
uint32_t max_Qm = is_ul?4:6; // Allow 16-QAM in PUSCH Only
int tbs = cqi_to_tbs(cqi, nof_prb, nof_re, max_mcs, max_Qm, &sel_mcs)/8;
/* If less bytes are requested, lower the MCS */
if (tbs > (int) req_bytes && req_bytes > 0) {

@ -58,8 +58,14 @@ void ue::config(uint16_t rnti_, uint32_t nof_prb, sched_interface *sched_, rrc_i
for(int i=0;i<NOF_HARQ_PROCESSES;i++) {
pending_buffers[i] = NULL;
}
// Set LCID group for SRB0 and SRB1
set_lcg(0, 0);
set_lcg(1, 0);
}
void ue::reset()
{
bzero(&metrics, sizeof(mac_metrics_t));
@ -87,6 +93,15 @@ void ue::rl_failure_reset()
nof_failures = 0;
}
void ue::set_lcg(uint32_t lcid, uint32_t lcg)
{
// find and remove if already exists
for (int i=0;i<4;i++) {
lc_groups[lcg].erase(std::remove(lc_groups[lcg].begin(), lc_groups[lcg].end(), lcid), lc_groups[lcg].end());
}
lc_groups[lcg].push_back(lcid);
}
srslte_softbuffer_rx_t* ue::get_rx_softbuffer(uint32_t tti)
{
return &softbuffer_rx[tti%NOF_HARQ_PROCESSES];
@ -137,10 +152,12 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, uint32_t tstamp)
pcap->write_ul_crnti(pdu, nof_bytes, rnti, true, last_tti);
}
uint32_t lcid_most_data = 0;
int most_data = -99;
while(mac_msg_ul.next()) {
assert(mac_msg_ul.get());
if (mac_msg_ul.get()->is_sdu())
{
if (mac_msg_ul.get()->is_sdu()) {
// Route logical channel
log_h->debug_hex(mac_msg_ul.get()->get_sdu_ptr(), mac_msg_ul.get()->get_payload_size(),
"PDU: rnti=0x%x, lcid=%d, %d bytes\n",
@ -154,7 +171,7 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, uint32_t tstamp)
if (mac_msg_ul.get()->get_sdu_lcid() == 0) {
uint8_t *x = mac_msg_ul.get()->get_sdu_ptr();
uint32_t sum = 0;
for (uint32_t i=0;i<mac_msg_ul.get()->get_payload_size();i++) {
for (uint32_t i = 0; i < mac_msg_ul.get()->get_payload_size(); i++) {
sum += x[i];
}
if (sum == 0) {
@ -173,25 +190,43 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, uint32_t tstamp)
// Indicate scheduler to update BSR counters
sched->ul_recv_len(rnti, mac_msg_ul.get()->get_sdu_lcid(), mac_msg_ul.get()->get_payload_size());
if ((int) mac_msg_ul.get()->get_payload_size() > most_data) {
most_data = (int) mac_msg_ul.get()->get_payload_size();
lcid_most_data = mac_msg_ul.get()->get_sdu_lcid();
}
// Save contention resolution if lcid == 0
if (mac_msg_ul.get()->get_sdu_lcid() == 0 && route_pdu) {
uint32_t nbytes = srslte::sch_subh::MAC_CE_CONTRES_LEN;
if (mac_msg_ul.get()->get_payload_size() >= nbytes) {
uint8_t *ue_cri_ptr = (uint8_t*) &conres_id;
uint8_t *ue_cri_ptr = (uint8_t *) &conres_id;
uint8_t *pkt_ptr = mac_msg_ul.get()->get_sdu_ptr(); // Warning here: we want to include the
for (uint32_t i=0;i<nbytes;i++) {
ue_cri_ptr[nbytes-i-1] = pkt_ptr[i];
for (uint32_t i = 0; i < nbytes; i++) {
ue_cri_ptr[nbytes - i - 1] = pkt_ptr[i];
}
} else {
Error("Received CCCH UL message of invalid size=%d bytes\n", mac_msg_ul.get()->get_payload_size());
}
}
} else {
}
}
mac_msg_ul.reset();
/* Process CE after all SDUs because we need to update BSR after */
bool bsr_received = false;
while(mac_msg_ul.next()) {
assert(mac_msg_ul.get());
if (!mac_msg_ul.get()->is_sdu()) {
// Process MAC Control Element
if (!process_ce(mac_msg_ul.get())) {
Warning("Received Subheader with invalid or unkonwn LCID\n");
bsr_received |= process_ce(mac_msg_ul.get());
}
}
// If BSR is not received means that new data has arrived and there is no space for BSR transmission
if (!bsr_received && lcid_most_data > 2) {
// Add BSR to the LCID for which most data was received
sched->ul_bsr(rnti, lcid_most_data, 256, false); // false adds BSR instead of setting
Debug("BSR not received. Giving extra grant\n");
}
Debug("MAC PDU processed\n");
@ -220,9 +255,10 @@ void ue::push_pdu(uint32_t tti, uint32_t len)
bool ue::process_ce(srslte::sch_subh *subh) {
uint32_t buff_size[4] = {0, 0, 0, 0};
uint32_t idx = 0;
float phr = 0;
int idx = 0;
uint16_t old_rnti = 0;
bool is_bsr = false;
switch(subh->ce_type()) {
case srslte::sch_subh::PHR_REPORT:
phr = subh->get_phr();
@ -242,22 +278,25 @@ bool ue::process_ce(srslte::sch_subh *subh) {
break;
case srslte::sch_subh::TRUNC_BSR:
case srslte::sch_subh::SHORT_BSR:
case srslte::sch_subh::LONG_BSR:
idx = subh->get_bsr(buff_size);
if (idx > 0) {
for (uint32_t i=0;i<lc_groups[idx].size();i++) {
// Indicate BSR to scheduler
sched->ul_bsr(rnti, idx, buff_size[idx]);
Info("CE: Received BSR rnti=0x%x, lcid=%d, value=%d\n", rnti, idx, buff_size[idx]);
} else if (idx == 0) {
// TODO: map lcid group to lcid
for (int i=0;i<4;i++) {
sched->ul_bsr(rnti, i, buff_size[i]);
sched->ul_bsr(rnti, lc_groups[idx][i], buff_size[idx]);
}
Info("CE: Received %s BSR rnti=0x%x, lcg=%d, value=%d\n",
subh->ce_type()==srslte::sch_subh::SHORT_BSR?"Short":"Trunc", rnti, idx, buff_size[idx]);
is_bsr = true;
break;
case srslte::sch_subh::LONG_BSR:
subh->get_bsr(buff_size);
for (int idx=0;idx<4;idx++) {
for (uint32_t i=0;i<lc_groups[idx].size();i++) {
sched->ul_bsr(rnti, lc_groups[idx][i], buff_size[idx]);
}
}
is_bsr = true;
Info("CE: Received Long BSR rnti=0x%x, value=%d,%d,%d,%d\n", rnti,
buff_size[0], buff_size[1], buff_size[2], buff_size[3]);
} else {
printf("Error!\n");
}
break;
case srslte::sch_subh::PADDING:
Debug("CE: Received padding for rnti=0x%x\n", rnti);
@ -266,7 +305,7 @@ bool ue::process_ce(srslte::sch_subh *subh) {
Error("CE: Invalid lcid=0x%x\n", subh->ce_type());
break;
}
return true;
return is_bsr;
}

@ -130,7 +130,7 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
bpo::value<int>(&args->expert.mac.sched.pusch_mcs)->default_value(-1),
"Optional fixed PUSCH MCS (ignores reported CQIs if specified)")
("scheduler.pusch_max_mcs",
bpo::value<int>(&args->expert.mac.sched.pusch_max_mcs)->default_value(16),
bpo::value<int>(&args->expert.mac.sched.pusch_max_mcs)->default_value(-1),
"Optional PUSCH MCS limit")
("scheduler.nof_ctrl_symbols",
bpo::value<int>(&args->expert.mac.sched.nof_ctrl_symbols)->default_value(3),
@ -152,7 +152,7 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
"Maximum number of turbo decoder iterations")
("expert.tx_amplitude",
bpo::value<float>(&args->expert.phy.tx_amplitude)->default_value(0.8),
bpo::value<float>(&args->expert.phy.tx_amplitude)->default_value(0.6),
"Transmit amplitude factor")
("expert.nof_phy_threads",
@ -176,7 +176,7 @@ void parse_args(all_args_t *args, int argc, char* argv[]) {
"Chooses the coefficients for the 3-tap channel estimator centered filter.")
("expert.rrc_inactivity_timer",
bpo::value<uint32_t>(&args->expert.rrc_inactivity_timer)->default_value(30000),
bpo::value<uint32_t>(&args->expert.rrc_inactivity_timer)->default_value(10000),
"Inactivity timer in ms")

@ -49,6 +49,8 @@ using namespace std;
#ifdef ENABLE_GUI
#include "srsgui/srsgui.h"
#include <semaphore.h>
#include <srslte/phy/phch/ra.h>
void init_plots(srsenb::phch_worker *worker);
pthread_t plot_thread;
sem_t plot_sem;
@ -109,7 +111,7 @@ void phch_worker::init(phch_common* phy_, srslte::log *log_h_)
return;
}
srslte_pucch_set_threshold(&enb_ul.pucch, 0.8, 0.5);
srslte_pucch_set_threshold(&enb_ul.pucch, 0.8);
srslte_sch_set_max_noi(&enb_ul.pusch.ul_sch, phy->params.pusch_max_its);
srslte_enb_dl_set_amp(&enb_dl, phy->params.tx_amplitude);
@ -355,7 +357,6 @@ int phch_worker::decode_pusch(srslte_enb_ul_pusch_t *grants, uint32_t nof_pusch,
}
if (cqi_enabled) {
uci_data.uci_cqi_len = srslte_cqi_size(&cqi_value);
Info("cqi enabled len=%d\n", uci_data.uci_cqi_len);
}
// mark this tti as having an ul grant to avoid pucch
@ -364,6 +365,10 @@ int phch_worker::decode_pusch(srslte_enb_ul_pusch_t *grants, uint32_t nof_pusch,
srslte_ra_ul_grant_t phy_grant;
int res = -1;
if (!srslte_ra_ul_dci_to_grant(&grants[i].grant, enb_ul.cell.nof_prb, n_rb_ho, &phy_grant, tti%8)) {
if (phy_grant.mcs.mod == SRSLTE_MOD_64QAM) {
phy_grant.mcs.mod = SRSLTE_MOD_16QAM;
}
phy_grant.Qm = SRSLTE_MIN(phy_grant.Qm, 4);
res = srslte_enb_ul_get_pusch(&enb_ul, &phy_grant, grants[i].softbuffer,
rnti, grants[i].rv_idx,
grants[i].current_tx_nb,

@ -83,11 +83,11 @@ void rlc::reset(uint16_t rnti)
void rlc::clear_buffer(uint16_t rnti)
{
if (users.count(rnti)) {
log_h->info("Clearing buffer rnti=0x%x\n", rnti);
users[rnti].rlc->reset();
users[rnti].rlc->empty_queue();
for (int i=0;i<SRSLTE_N_RADIO_BEARERS;i++) {
mac->rlc_buffer_state(rnti, i, 0, 0);
}
log_h->info("Cleared buffer rnti=0x%x\n", rnti);
}
}

@ -24,6 +24,8 @@
*
*/
#include <srslte/interfaces/sched_interface.h>
#include <srslte/asn1/liblte_rrc.h>
#include "srslte/asn1/liblte_mme.h"
#include "upper/rrc.h"
@ -312,12 +314,11 @@ void rrc::release_complete(uint16_t rnti)
if (!users[rnti].is_idle()) {
rlc->clear_buffer(rnti);
users[rnti].send_connection_release();
// There is no RRCReleaseComplete message from UE thus sleep to enable all retx in PHY +50%
usleep(1.5*8*1e3*cfg.mac_cnfg.ulsch_cnfg.max_harq_tx);
// There is no RRCReleaseComplete message from UE thus wait ~100 subframes for tx
usleep(100000);
}
rem_user(rnti);
} else {
rrc_log->error("Received ReleaseComplete for unknown rnti=0x%x\n", rnti);
}
}
@ -437,7 +438,7 @@ void rrc::add_paging_id(uint32_t ueid, LIBLTE_S1AP_UEPAGINGID_STRUCT UEPagingID)
// Described in Section 7 of 36.304
bool rrc::is_paging_opportunity(uint32_t tti, uint32_t *payload_len)
{
int sf_pattern[4][3] = {{9, 4, 0}, {-1, 9, 4}, {-1, -1, 5}, {-1, -1, 9}};
int sf_pattern[4][4] = {{9, 4, -1, 0}, {-1, 9, -1, 4}, {-1, -1, -1, 5}, {-1, -1, -1, 9}};
if (pending_paging.empty()) {
return false;
@ -466,7 +467,7 @@ bool rrc::is_paging_opportunity(uint32_t tti, uint32_t *payload_len)
if ((sfn % T) == (T/N) * (ueid % N)) {
int sf_idx = sf_pattern[i_s%4][(Ns-1)%3];
int sf_idx = sf_pattern[i_s%4][(Ns-1)%4];
if (sf_idx < 0) {
rrc_log->error("SF pattern is N/A for Ns=%d, i_s=%d, imsi_decimal=%d\n", Ns, i_s, ueid);
} else if ((uint32_t) sf_idx == (tti%10)) {
@ -1311,7 +1312,9 @@ void rrc::ue::send_connection_reconf(srslte::byte_buffer_t *pdu)
// Add SRB2 and DRB1 to the scheduler
srsenb::sched_interface::ue_bearer_cfg_t bearer_cfg;
bearer_cfg.direction = srsenb::sched_interface::ue_bearer_cfg_t::BOTH;
bearer_cfg.group = 0;
parent->mac->bearer_ue_cfg(rnti, 2, &bearer_cfg);
bearer_cfg.group = conn_reconf->rr_cnfg_ded.drb_to_add_mod_list[0].lc_cnfg.ul_specific_params.log_chan_group;
parent->mac->bearer_ue_cfg(rnti, 3, &bearer_cfg);
// Configure SRB2 in RLC and PDCP

@ -173,7 +173,7 @@ void s1ap::build_tai_cgi()
void s1ap::initial_ue(uint16_t rnti, srslte::byte_buffer_t *pdu)
{
ue_ctxt_map[rnti].eNB_UE_S1AP_ID = next_eNB_UE_S1AP_ID++;
ue_ctxt_map[rnti].stream_id = next_ue_stream_id++;
ue_ctxt_map[rnti].stream_id = 1;
ue_ctxt_map[rnti].release_requested = false;
enbid_to_rnti_map[ue_ctxt_map[rnti].eNB_UE_S1AP_ID] = rnti;
send_initialuemessage(rnti, pdu, false);
@ -182,7 +182,7 @@ void s1ap::initial_ue(uint16_t rnti, srslte::byte_buffer_t *pdu)
void s1ap::initial_ue(uint16_t rnti, srslte::byte_buffer_t *pdu, uint32_t m_tmsi, uint8_t mmec)
{
ue_ctxt_map[rnti].eNB_UE_S1AP_ID = next_eNB_UE_S1AP_ID++;
ue_ctxt_map[rnti].stream_id = next_ue_stream_id++;
ue_ctxt_map[rnti].stream_id = 1;
ue_ctxt_map[rnti].release_requested = false;
enbid_to_rnti_map[ue_ctxt_map[rnti].eNB_UE_S1AP_ID] = rnti;
send_initialuemessage(rnti, pdu, true, m_tmsi, mmec);
@ -594,7 +594,7 @@ bool s1ap::handle_uectxtreleasecommand(LIBLTE_S1AP_MESSAGE_UECONTEXTRELEASECOMMA
s1ap_log->warning("Not handling S1AP message extension\n");
}
uint16_t rnti;
uint16_t rnti = 0;
if(msg->UE_S1AP_IDs.choice_type == LIBLTE_S1AP_UE_S1AP_IDS_CHOICE_UE_S1AP_ID_PAIR) {
if(msg->UE_S1AP_IDs.choice.uE_S1AP_ID_pair.ext) {

@ -27,6 +27,7 @@
#include <unistd.h>
#include <sstream>
#include <srslte/asn1/liblte_rrc.h>
#include "upper/rrc.h"
#include "srslte/phy/utils/bit.h"
@ -78,7 +79,14 @@ void rrc::init(phy_interface_rrc *phy_,
nas = nas_;
usim = usim_;
rrc_log = rrc_log_;
// Use MAC timers
mac_timers = mac_timers_;
t301 = mac_timers->get_unique_id();
t310 = mac_timers->get_unique_id();
t311 = mac_timers->get_unique_id();
safe_reset_timer = mac_timers->get_unique_id();
pthread_mutex_init(&mutex, NULL);
@ -1084,8 +1092,11 @@ void rrc::apply_phy_config_dedicated(LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT
current_cfg->ul_pwr_ctrl_ded.accumulation_en = true;
current_cfg->ul_pwr_ctrl_ded.p0_ue_pucch = 0;
current_cfg->ul_pwr_ctrl_ded.p_srs_offset = 7;
}
if (phy_cnfg->ul_pwr_ctrl_ded.filter_coeff_present) {
current_cfg->ul_pwr_ctrl_ded.filter_coeff = phy_cnfg->ul_pwr_ctrl_ded.filter_coeff;
} else {
current_cfg->ul_pwr_ctrl_ded.filter_coeff = LIBLTE_RRC_FILTER_COEFFICIENT_FC4;
current_cfg->ul_pwr_ctrl_ded.filter_coeff_present = true;
}
if(phy_cnfg->tpc_pdcch_cnfg_pucch_present) {
memcpy(&current_cfg->tpc_pdcch_cnfg_pucch, &phy_cnfg->tpc_pdcch_cnfg_pucch, sizeof(LIBLTE_RRC_TPC_PDCCH_CONFIG_STRUCT));
@ -1488,10 +1499,6 @@ void rrc::set_mac_default()
void rrc::set_rrc_default() {
N310 = 1;
N311 = 1;
t301 = mac_timers->get_unique_id();
t310 = mac_timers->get_unique_id();
t311 = mac_timers->get_unique_id();
safe_reset_timer = mac_timers->get_unique_id();
mac_timers->get(t310)->set(this, 1000);
mac_timers->get(t311)->set(this, 1000);
mac_timers->get(safe_reset_timer)->set(this, 10);

@ -23,10 +23,10 @@
[rf]
dl_freq = 2685000000
ul_freq = 2565000000
tx_gain = 70
rx_gain = 50
tx_gain = 80
rx_gain = 60
#nof_rx_ant = 1
nof_rx_ant = 2
#device_name = auto
#device_args = auto
#time_adv_nsamples = auto

Loading…
Cancel
Save