Fixed some UL/DL HARQ issues in MAC. Now working OK until ConnectionSetup reception

This commit is contained in:
ismagom 2015-05-27 13:27:49 +02:00
parent 5672908173
commit d46622d802
30 changed files with 325 additions and 234 deletions

View File

@ -58,22 +58,9 @@ namespace srslte {
virtual void start_rx() = 0;
virtual void stop_rx() = 0;
float get_tx_gain() { return cur_tx_gain; }
float get_rx_gain() { return cur_rx_gain; }
virtual float get_tx_gain() = 0;
virtual float get_rx_gain() = 0;
float get_tx_freq() { return cur_tx_freq; }
float get_rx_freq() { return cur_rx_freq; }
float get_tx_srate() { return cur_tx_srate; }
float get_rx_srate() { return cur_rx_srate; }
protected:
float cur_tx_gain;
float cur_rx_gain;
float cur_tx_freq;
float cur_rx_freq;
float cur_tx_srate;
float cur_rx_srate;
};
}

View File

@ -63,6 +63,10 @@ namespace srslte {
void set_tx_srate(float srate);
void set_rx_srate(float srate);
float get_tx_gain();
float get_rx_gain();
void start_rx();
void stop_rx();

View File

@ -96,38 +96,47 @@ bool radio_uhd::tx(void* buffer, uint32_t nof_samples, srslte_timestamp_t tx_tim
void radio_uhd::set_rx_freq(float freq)
{
cur_rx_freq = cuhd_set_rx_freq(uhd, freq);
cuhd_set_rx_freq(uhd, freq);
}
void radio_uhd::set_rx_gain(float gain)
{
cur_rx_gain = cuhd_set_rx_gain(uhd, gain);
cuhd_set_rx_gain(uhd, gain);
}
double radio_uhd::set_rx_gain_th(float gain)
{
cur_rx_gain = cuhd_set_rx_gain_th(uhd, gain);
return cur_rx_gain;
return cuhd_set_rx_gain_th(uhd, gain);
}
void radio_uhd::set_rx_srate(float srate)
{
cur_rx_srate = cuhd_set_rx_srate(uhd, srate);
cuhd_set_rx_srate(uhd, srate);
}
void radio_uhd::set_tx_freq(float freq)
{
cur_tx_freq = cuhd_set_tx_freq(uhd, freq);
cuhd_set_tx_freq(uhd, freq);
}
void radio_uhd::set_tx_gain(float gain)
{
cur_tx_gain = cuhd_set_tx_gain(uhd, gain);
cuhd_set_tx_gain(uhd, gain);
}
float radio_uhd::get_tx_gain()
{
return cuhd_get_tx_gain(uhd);
}
float radio_uhd::get_rx_gain()
{
return cuhd_get_rx_gain(uhd);
}
void radio_uhd::set_tx_srate(float srate)
{
cur_tx_srate = cuhd_set_tx_srate(uhd, srate);
cuhd_set_tx_srate(uhd, srate);
}
void radio_uhd::start_rx()

View File

@ -112,7 +112,7 @@ private:
int tti;
bool started = false;
bool is_synchronized;
bool is_first_temporal;
uint16_t last_temporal_crnti;
/* Multiplexing/Demultiplexing Units */
mux mux_unit;

View File

@ -202,6 +202,7 @@ public:
bool set_ta_cmd(uint8_t ta_cmd);
bool set_phd(uint8_t phd);
void set_padding();
void set_padding(uint32_t padding_len);
void init();
void fprint(FILE *stream);

View File

@ -77,8 +77,8 @@ private:
log *log_h;
bool initiated;
const static int MAX_LCID = 20;
uint32_t lcg[MAX_LCID];
uint32_t priorities[MAX_LCID];
int lcg[MAX_LCID];
int priorities[MAX_LCID];
uint32_t find_max_priority_lcid();
enum {NONE, REGULAR, PADDING, PERIODIC} triggered_bsr_type;
bool timer_periodic;
@ -88,6 +88,7 @@ private:
bool sr_is_sent;
bool check_all_channels();
bool check_highest_channel();
bool check_single_channel();
void get_pending_bsr_format(uint32_t nof_padding_bytes);
};

View File

@ -78,6 +78,7 @@ private:
void set_harq_feedback(bool ack);
bool get_ndi();
uint32_t last_tx_tti();
uint32_t pid;
private:
uint32_t current_tx_nb;

View File

@ -92,6 +92,7 @@ void demux::push_pdu_temp_crnti(uint8_t *mac_pdu, uint32_t nof_bits)
// Unpack DLSCH MAC PDU
pending_mac_msg.init(nof_bits/8);
pending_mac_msg.parse_packet(mac_pdu);
pending_mac_msg.fprint(stdout);
// Look for Contention Resolution UE ID
while(pending_mac_msg.next()) {
@ -115,6 +116,7 @@ void demux::push_pdu(uint8_t *mac_pdu, uint32_t nof_bits)
// Unpack DLSCH MAC PDU
mac_msg.init(nof_bits/8);
mac_msg.parse_packet(mac_pdu);
mac_msg.fprint(stdout);
process_pdu(&mac_msg);
Debug("Normal MAC PDU processed\n");
}
@ -130,7 +132,6 @@ void demux::demultiplex_pending_pdu()
if (pending_temp_rnti) {
process_pdu(&pending_mac_msg);
discard_pending_pdu();
Info("Temporal C-RNTI MAC PDU processed\n");
} else {
Error("Error demultiplex pending PDU: No pending PDU\n");
}
@ -140,7 +141,6 @@ void demux::demultiplex_pending_pdu()
void demux::process_pdu(sch_pdu *pdu_msg)
{
Info("Processing PDU\n");
while(pdu_msg->next()) {
if (pdu_msg->get()->is_sdu()) {
// Route logical channel
@ -148,7 +148,7 @@ void demux::process_pdu(sch_pdu *pdu_msg)
qbuff *dest_lch = mac_io_h->get(pdu_msg->get()->get_sdu_lcid());
if (dest_lch) {
dest_lch->send(pdu_msg->get()->get_sdu_ptr(), pdu_msg->get()->get_sdu_nbytes()*8);
Info("Sent MAC SDU len=%d bytes to lchid=%d\n",
Debug("Sent MAC SDU len=%d bytes to lchid=%d\n",
pdu_msg->get()->get_sdu_nbytes(), pdu_msg->get()->get_sdu_lcid());
} else {
Error("Getting destination channel LCID=%d\n", pdu_msg->get()->get_sdu_lcid());

View File

@ -122,7 +122,6 @@ void dl_harq_entity::dl_harq_process::reset() {
void dl_harq_entity::dl_harq_process::send_pending_ack_contention_resolution()
{
if (pending_ul_buffer) {
Info("Generating Pending ACK=%d for UL TTI=%d\n", pending_ack, pending_ul_buffer->tti);
pending_ul_buffer->generate_ack(pending_ack, &pending_ack_grant);
}
}
@ -134,9 +133,7 @@ void dl_harq_entity::dl_harq_process::receive_data(uint32_t tti, srslte::ue::dl_
if (payload) {
if (cur_grant.get_tbs() <= max_payload_len) {
Info("Decoding PDSCH data TBS=%d, RV=%d\n", cur_grant.get_tbs(), cur_grant.get_rv());
if (dl_buffer->decode_data(&cur_grant, &softbuffer, payload)) {
Info("Decoded OK\n");
// RX OK
if (pid == HARQ_BCCH_PID) {
Debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (BCCH)\n", cur_grant.get_tbs()/8);
@ -155,7 +152,6 @@ void dl_harq_entity::dl_harq_process::receive_data(uint32_t tti, srslte::ue::dl_
ack = true;
}
} else {
Warning("Decoded Error\n");
// RX NOK
ack = false;
}
@ -181,21 +177,34 @@ void dl_harq_entity::dl_harq_process::receive_data(uint32_t tti, srslte::ue::dl_
fprintf(stderr, "Error with DL grant. TBS (%d) exceeds payload buffer length (%d)\n", cur_grant.get_tbs(), max_payload_len);
}
}
Info("DL PID %d: TBS=%d, RV=%d, MCS=%d, crc=%s\n", pid, cur_grant.get_tbs(), cur_grant.get_rv(), cur_grant.get_mcs(), ack?"OK":"NOK");
}
// Implement 5.3.2.2
void dl_harq_entity::dl_harq_process::set_harq_info(srslte::ue::dl_sched_grant* new_grant) {
bool is_new_transmission = false;
if (new_grant->get_ndi() && !cur_grant.get_ndi() || is_first_tx) {
if (new_grant->get_ndi() != cur_grant.get_ndi() || is_first_tx) {
is_new_transmission = true;
is_first_decoded = true;
is_first_tx = false;
Debug("Set HARQ Info for new transmission\n");
} else {
is_new_transmission = false;
Debug("Set HARQ Info for retransmission\n");
}
if (is_first_tx) {
Info("DL PID %d: first TX RV=%d, NDI=%d\n", pid, new_grant->get_rv(), new_grant->get_ndi());
} else {
Info("DL PID %d: %s RV=%d, NDI=%d, LastNDI=%d\n", pid, is_new_transmission?"new TX":"reTX", new_grant->get_rv(), new_grant->get_ndi(), cur_grant.get_ndi());
}
if (is_first_tx) {
is_first_tx = false;
}
if (is_new_transmission || cur_grant.get_tbs() != new_grant->get_tbs()) {
Debug("Reset softbuffer RX\n");
srslte_softbuffer_rx_reset(&softbuffer);
}
if (new_grant->get_tbs() <= max_payload_len) {

View File

@ -46,6 +46,7 @@ bool mac::init(phy *phy_h_, tti_sync* ttisync_, log* log_h_)
log_h = log_h_;
tti = 0;
is_synchronized = false;
last_temporal_crnti = 0;
bsr_procedure.init(log_h, &timers_db, &params_db, &mac_io_lch);
mux_unit.init(log_h, &mac_io_lch, &bsr_procedure);
@ -169,7 +170,6 @@ void mac::main_radio_loop() {
}
if (is_synchronized) {
/* Warning: Here order of invocation of procedures is important!! */
bool ul_resources_available;
tti = ttisync->wait();
log_h->step(tti);
@ -177,7 +177,9 @@ void mac::main_radio_loop() {
bsr_procedure.step(tti);
// Check if BSR procedure need to start SR
if (bsr_procedure.need_to_send_sr()) {
Info("Starting SR procedure by BSR request\n");
sr_procedure.start();
}
sr_procedure.step(tti);
@ -188,8 +190,6 @@ void mac::main_radio_loop() {
}
ra_procedure.step(tti);
//phr_procedure.step(tti);
// Receive PCH, if requested
@ -202,7 +202,7 @@ void mac::main_radio_loop() {
if (ra_procedure.is_contention_resolution() ||
ra_procedure.is_successful() && mux_unit.is_pending_ccch_sdu())
{
ul_resources_available = process_ul_grants(tti);
process_ul_grants(tti);
}
// Send pending HARQ ACK, if any, and contention resolution is resolved
@ -318,14 +318,13 @@ void mac::process_dl_grants(uint32_t tti) {
}
if (i != mac_params::RNTI_SPS) {
uint32_t harq_pid = ue_grant.get_harq_process();
if (i == mac_params::RNTI_TEMP) {
ue_grant.set_ndi(is_first_temporal);
is_first_temporal = false;
if (i == mac_params::RNTI_TEMP && last_temporal_crnti != params_db.get_param(i)) {
ue_grant.set_ndi(true);
last_temporal_crnti = params_db.get_param(i);
}
if (i == mac_params::RNTI_C && dl_harq.is_sps(harq_pid)) {
ue_grant.set_ndi(true);
}
Info("Processing DL grant TBS=%d, RNTI=%d, RV=%d\n", ue_grant.get_tbs(), ue_grant.get_rnti(), ue_grant.get_rv());
dl_harq.set_harq_info(harq_pid, &ue_grant);
dl_harq.receive_data(tti, harq_pid, dl_buffer, phy_h);
} else {
@ -415,7 +414,6 @@ bool mac::process_ul_grants(uint32_t tti) {
if (i == mac_params::RNTI_C && ul_harq.is_sps(tti)) {
ul_grant.set_ndi(true);
}
Info("Found UL Grant TBS=%d RNTI=%d is_from_rar=%d\n", ul_grant.get_tbs(), params_db.get_param(i), ul_grant.is_from_rar());
ul_harq.run_tti(tti, &ul_grant, phy_h);
return true;
}

View File

@ -85,6 +85,11 @@ void sch_pdu::parse_packet(uint8_t *ptr)
bool sch_pdu::write_packet(uint8_t* ptr)
{
uint8_t *init_ptr = ptr;
bool last_is_padding = false;
// Add multi-byte padding if necessary
if (rem_len > 2) {
last_is_padding = true;
}
// Add single or two-byte padding if required
if (rem_len == 1 || rem_len == 2) {
sch_subh padding;
@ -94,6 +99,8 @@ bool sch_pdu::write_packet(uint8_t* ptr)
}
rem_len = 0;
}
int last_sh;
if (!last_is_padding) {
// Find last SDU or CE
int last_sdu = nof_subheaders-1;
while(!subheaders[last_sdu].is_sdu() && last_sdu >= 0) {
@ -103,7 +110,10 @@ bool sch_pdu::write_packet(uint8_t* ptr)
while(subheaders[last_ce].is_sdu() && last_ce >= 0) {
last_ce--;
}
int last_sh = subheaders[last_sdu].is_sdu()?last_sdu:last_ce;
last_sh = subheaders[last_sdu].is_sdu()?last_sdu:last_ce;
} else {
last_sh = -1;
}
// Write subheaders for MAC CE first
for (int i=0;i<nof_subheaders;i++) {
if (!subheaders[i].is_sdu()) {
@ -116,6 +126,11 @@ bool sch_pdu::write_packet(uint8_t* ptr)
subheaders[i].write_subheader(&ptr, i==last_sh);
}
}
if (last_is_padding) {
sch_subh padding;
padding.set_padding(rem_len);
padding.write_subheader(&ptr, true);
}
// Write payloads in the same order
for (int i=0;i<nof_subheaders;i++) {
if (!subheaders[i].is_sdu()) {
@ -279,10 +294,16 @@ uint8_t* sch_subh::get_sdu_ptr()
{
return sdu_payload_ptr;
}
void sch_subh::set_padding()
void sch_subh::set_padding(uint32_t padding_len)
{
lcid = PADDING;
nof_bytes = padding_len;
}
void sch_subh::set_padding()
{
set_padding(0);
}
bool sch_subh::set_bsr(uint32_t buff_size[4], sch_subh::cetype format)
{
@ -416,7 +437,7 @@ bool sch_subh::read_subheader(uint8_t** ptr)
if (is_sdu()) {
if (e_bit) {
F_bit = srslte_bit_unpack(ptr, 1)?true:false;
nof_bytes = srslte_bit_unpack(ptr, F_bit?7:15);
nof_bytes = srslte_bit_unpack(ptr, F_bit?15:7);
} else {
nof_bytes = 0;
F_bit = 0;

View File

@ -39,14 +39,15 @@ bsr_proc::bsr_proc()
timer_periodic = false;
timer_retx = false;
for (int i=0;i<MAX_LCID;i++) {
lcg[i] = 0;
priorities[i] = 0;
lcg[i] = -1;
priorities[i] = -1;
}
triggered_bsr_type=NONE;
}
void bsr_proc::init(log* log_h_, timers *timers_db_, mac_params* params_db_, mac_io *mac_io_h_)
{
log_h = log_h;
log_h = log_h_;
params_db = params_db_;
mac_io_h = mac_io_h_;
timers_db = timers_db_;
@ -66,12 +67,14 @@ void bsr_proc::timer_expired(uint32_t timer_id) {
// Check condition 4 in Sec 5.4.5
if (check_all_channels()) {
triggered_bsr_type = PERIODIC;
Info("BSR set to PERIODIC\n");
}
}
break;
case mac::BSR_TIMER_RETX:
// Check condition 3 in Sec 5.4.5
if (check_all_channels()) {
Info("BSR set to REGULAR RETX\n");
triggered_bsr_type = REGULAR;
sr_is_sent = false; // Enable reTx of SR
}
@ -79,56 +82,71 @@ void bsr_proc::timer_expired(uint32_t timer_id) {
}
}
/* Checks condition 1 for Regular BSR reporting */
// Checks if data is available for a a channel with higher priority than others
bool bsr_proc::check_highest_channel() {
uint32_t lcg_with_data = 0;
uint32_t pending_data = 0;
uint32_t min_priority_group[4]={99, 99, 99, 99};
bool trigger_bsr = true;
uint32_t pending_data_lcid = 0;
// Check if data arrived for a LCG
for (uint32_t group=0;group<4;group++) {
for (int i=0;i<mac_io::NOF_UL_LCH;i++) {
if (lcg[group] == i) {
if (priorities[i] < min_priority_group[group]) {
min_priority_group[group] = priorities[i];
}
pending_data = mac_io_h->get(i)->pending_data();
for (int i=0;i<mac_io::NOF_UL_LCH && !pending_data;i++) {
if (lcg[i] >= 0) {
pending_data = mac_io_h->get(i+mac_io::MAC_LCH_CCCH_UL)->pending_data()/8;
if (pending_data > 0) {
lcg_with_data = group;
pending_data_lcid = i;
for (int j=0;j<mac_io::NOF_UL_LCH;j++) {
if (!mac_io_h->get(j+mac_io::MAC_LCH_CCCH_UL)->isempty()) {
if (priorities[j] > priorities[i]) {
pending_data = 0;
}
}
}
}
}
}
if (pending_data) {
// If no data is available belonging to any of the logical channels belonging to any other LCG
for (uint32_t group=0;group<4 && trigger_bsr;group++) {
if (group != lcg_with_data) {
for (int i=0;i<mac_io::NOF_UL_LCH && trigger_bsr;i++) {
if (lcg[group] == i) {
if (mac_io_h->get(i)->pending_data() && priorities[i] > min_priority_group[group]) {
trigger_bsr=false;
}
}
}
}
pending_bsr.buff_size[lcg[pending_data_lcid]] = pending_data;
triggered_bsr_type = REGULAR;
Info("Triggered REGULAR BSR for Max Priority LCID=%d\n", pending_data_lcid);
return true;
} else {
return false;
}
}
return trigger_bsr;
// Checks if only one logical channel has data avaiable for Tx
bool bsr_proc::check_single_channel() {
uint32_t pending_data_lcid = 0;
uint32_t nof_nonzero_lcid = 0;
for (int i=0;i<mac_io::NOF_UL_LCH;i++) {
if (lcg[i] >= 0) {
if (!mac_io_h->get(i+mac_io::MAC_LCH_CCCH_UL)->isempty()) {
pending_data_lcid = i;
nof_nonzero_lcid++;
}
}
}
if (nof_nonzero_lcid == 1) {
pending_bsr.buff_size[lcg[pending_data_lcid]] = mac_io_h->get(pending_data_lcid+mac_io::MAC_LCH_CCCH_UL)->pending_data()/8;
triggered_bsr_type = REGULAR;
Info("Triggered REGULAR BSR for single LCID=%d\n", pending_data_lcid);
return true;
} else {
return false;
}
}
bool bsr_proc::check_all_channels() {
bool ret = false;
bzero(&pending_bsr, sizeof(bsr_t));
for (int i=0;i<mac_io_h->NOF_UL_LCH;i++) {
uint32_t n = mac_io_h->get(i)->pending_data();
if (lcg[i] >= 0) {
uint32_t n = mac_io_h->get(i+mac_io::MAC_LCH_CCCH_UL)->pending_data()/8;
pending_bsr.buff_size[lcg[i]] += n;
if (n > 0) {
ret = true;
}
}
}
return ret;
}
@ -190,10 +208,10 @@ void bsr_proc::step(uint32_t tti)
// Check condition 1 in Sec 5.4.5
if (triggered_bsr_type == NONE) {
if (check_highest_channel()) {
triggered_bsr_type = REGULAR;
}
check_single_channel();
}
// Higher priority channel is reported regardless of a BSR being already triggered
check_highest_channel();
}
bool bsr_proc::need_to_send_bsr_on_ul_grant(uint32_t nof_grant_bytes, uint32_t nof_padding_bytes, bsr_t *bsr)
@ -215,16 +233,16 @@ bool bsr_proc::need_to_send_bsr_on_ul_grant(uint32_t nof_grant_bytes, uint32_t n
for (int i=0;i<4;i++) {
nof_pending_bytes += pending_bsr.buff_size[i];
}
// Do not include BSR CE if the UL grant can accomodate all pending data but is not sufficient
// to additionally accomodate the BSR MAC CE plus its header
uint32_t bsr_sz_plus_header = 1 + pending_bsr.format == LONG_BSR?3:1;
if (nof_pending_bytes + bsr_sz_plus_header == nof_grant_bytes) {
// if nof_pending_bytes + bsr_sz_plus_header > nof_grant_bytes, BSR has higher priority than data
return false;
}
Info("Triggered BSR: nof_grant_bytes=%d, nof_padding_bytes=%d, nof_pending_bytes=%d\n", nof_grant_bytes, nof_padding_bytes, nof_pending_bytes);
get_pending_bsr_format(nof_padding_bytes);
// Do not include BSR CE if the UL grant can accomodate all pending data but is not sufficient
// to additionally accomodate the BSR MAC CE plus its header
uint32_t bsr_sz_plus_header = pending_bsr.format == LONG_BSR?4:2;
if (nof_pending_bytes + bsr_sz_plus_header == nof_grant_bytes) {
triggered_bsr_type = NONE;
} else {
// Instruct MUX unit to generate MAC CE
ret = true;
memcpy(bsr, &pending_bsr, sizeof(bsr_t));
@ -235,6 +253,7 @@ bool bsr_proc::need_to_send_bsr_on_ul_grant(uint32_t nof_grant_bytes, uint32_t n
// Cancel all triggered BSR
triggered_bsr_type = NONE;
}
}
// Restart or Start ReTX timer
if (timer_retx) {

View File

@ -170,7 +170,6 @@ void ra_proc::process_timeadv_cmd(uint32_t ta) {
void* init_prach_thread(void *arg) {
phy* phy_h = (phy*) arg;
printf("thread initiating prach\n");
if (phy_h->init_prach()) {
return (void*) 0;
} else {
@ -234,6 +233,7 @@ void ra_proc::step_resource_selection() {
}
sel_maskIndex = 0;
}
rInfo("Selected preambleIndex=%d maskIndex=%d nof_GroupApreambles=%d\n", sel_preamble, sel_maskIndex,nof_groupA_preambles);
state = PREAMBLE_TRANSMISSION;
}
@ -353,7 +353,7 @@ void ra_proc::step_response_reception() {
void ra_proc::step_response_error() {
preambleTransmissionCounter++;
if (preambleTransmissionCounter == preambleTransMax + 1) {
if (preambleTransmissionCounter >= preambleTransMax + 1) {
rError("Maximum number of transmissions reached (%d)\n", preambleTransMax);
state = RA_PROBLEM;
} else {
@ -367,7 +367,7 @@ void ra_proc::step_response_error() {
rInfo("Backoff wait interval %d\n", backoff_inteval);
state = BACKOFF_WAIT;
} else {
rInfo("Transmitting inmediatly\n");
rInfo("Transmitting inmediatly (%d/%d)\n", preambleTransmissionCounter, preambleTransMax);
state = RESOURCE_SELECTION;
}
}
@ -481,6 +481,7 @@ void ra_proc::start_mac_order()
if (state == IDLE || state == COMPLETION || state == RA_PROBLEM) {
start_mode = MAC_ORDER;
state = INITIALIZATION;
Info("Starting PRACH by MAC order\n");
run();
}
}
@ -490,6 +491,7 @@ void ra_proc::start_pdcch_order()
if (state == IDLE || state == COMPLETION || state == RA_PROBLEM) {
start_mode = PDCCH_ORDER;
state = INITIALIZATION;
Info("Starting PRACH by PDCCH order\n");
run();
}
}
@ -499,6 +501,7 @@ void ra_proc::start_rlc_order()
if (state == IDLE || state == COMPLETION || state == RA_PROBLEM) {
start_mode = RLC_ORDER;
state = INITIALIZATION;
Info("Starting PRACH by RLC CCCH SDU order\n");
run();
}
}

View File

@ -56,6 +56,7 @@ void sr_proc::step(uint32_t tti)
if (is_pending_sr) {
if (sr_counter < dsr_transmax) {
sr_counter++;
Info("SR stepping: sr_counter=%d\n", sr_counter);
phy_h->send_sr(true);
} else {
reset();
@ -66,8 +67,10 @@ void sr_proc::step(uint32_t tti)
bool sr_proc::need_random_access() {
if (initiated) {
if (sr_counter == dsr_transmax && dsr_transmax > 0 ||
!params_db->get_param(mac_params::SR_PUCCH_CONFIGURED)) {
if (sr_counter == dsr_transmax && dsr_transmax > 0 &&
params_db->get_param(mac_params::SR_PUCCH_CONFIGURED)) {
Info("SR checking need RA: sr_counter=%d, dsr_transmax=%d, configured=%d\n", sr_counter, dsr_transmax, params_db->get_param(mac_params::SR_PUCCH_CONFIGURED));
return true;
} else {
return false;
@ -82,6 +85,7 @@ void sr_proc::start()
if (!is_pending_sr) {
sr_counter = 0;
dsr_transmax = params_db->get_param(mac_params::SR_TRANS_MAX);
Info("SR starting dsrTransMax=%d. Setting sr_counter=0\n", dsr_transmax);
}
}
}

View File

@ -50,6 +50,7 @@ bool ul_harq_entity::init(srslte_cell_t cell, mac_params *params_db_, log *log_h
if (!proc[i].init(cell, this)) {
return false;
}
proc[i].pid = i;
}
return true;
}
@ -88,7 +89,6 @@ void ul_harq_entity::run_tti(uint32_t tti, ul_sched_grant *grant, phy *phy_h)
}
uint32_t pid_harq = pidof(tti_harq);
if (proc[pid_harq].has_grant() && proc[pid_harq].last_tx_tti() <= tti_harq) {
Info("Receiving HARQ feedback for PID=%d, TTI last TX %d, TTI harq %d\n", pid_harq, proc[pid_harq].last_tx_tti(), tti_harq);
proc[pid_harq].set_harq_feedback(phy_h->get_dl_buffer(tti)->decode_ack(proc[pid_harq].get_grant()));
}
@ -103,7 +103,6 @@ void ul_harq_entity::run_tti(uint32_t tti, ul_sched_grant *grant, phy *phy_h)
// Uplink grant in a RAR
if (grant->is_from_rar()) {
if (msg3_ptr) {
Info("Generating New Msg3 Transmission for PID=%d TTI=%d\n", pid, tti_tx);
proc[pid].generate_new_tx(tti_tx, msg3_ptr, true, grant, phy_h->get_ul_buffer(tti_tx));
mux_unit->msg3_transmitted();
} else {
@ -113,7 +112,6 @@ void ul_harq_entity::run_tti(uint32_t tti, ul_sched_grant *grant, phy *phy_h)
// Normal UL grant
} else {
// Request a MAC PDU from the Multiplexing & Assemble Unit
Info("Generating New Transmission for PID=%d TTI=%d\n", pid, tti_tx);
uint8_t* mac_pdu = mux_unit->pdu_pop(grant->get_tbs());
if (mac_pdu) {
proc[pid].generate_new_tx(tti_tx, mac_pdu, false, grant, phy_h->get_ul_buffer(tti_tx));
@ -124,12 +122,10 @@ void ul_harq_entity::run_tti(uint32_t tti, ul_sched_grant *grant, phy *phy_h)
}
} else {
// Adaptive Re-TX
Info("Generating Adaptive Retransmission for PID=%d RV=%d\n", pid, proc[pid].get_rv());
proc[pid].generate_retx(tti_tx, grant, phy_h->get_ul_buffer(tti_tx));
}
} else if (proc[pid].has_grant()) {
// Non-Adaptive Re-Tx
Info("Generating Non-adaptive Retransmission for PID=%d RV=%d\n", pid, proc[pid].get_rv());
proc[pid].generate_retx(tti_tx, phy_h->get_ul_buffer(tti_tx));
}
@ -189,10 +185,10 @@ void ul_harq_entity::ul_harq_process::set_harq_feedback(bool ack) {
harq_feedback = ack;
// UL packet successfully delivered
if (ack) {
Info("HARQ = ACK for UL transmission. Discarting TB.\n");
Info("UL PID %d: HARQ = ACK for UL transmission. Discarting TB.\n", pid);
reset();
} else {
Info("HARQ = NACK for UL transmission\n");
Info("UL PID %d: HARQ = NACK for UL transmission\n", pid);
}
}
@ -208,6 +204,11 @@ bool ul_harq_entity::ul_harq_process::init(srslte_cell_t cell, ul_harq_entity *p
}
}
void ul_harq_entity::ul_harq_process::generate_retx(uint32_t tti_tx, ul_buffer* ul)
{
generate_retx(tti_tx, NULL, ul);
}
// Retransmission with or w/o grant (Section 5.4.2.2)
void ul_harq_entity::ul_harq_process::generate_retx(uint32_t tti_tx, ul_sched_grant* grant, ul_buffer* ul)
{
@ -217,8 +218,10 @@ void ul_harq_entity::ul_harq_process::generate_retx(uint32_t tti_tx, ul_sched_gr
memcpy(&cur_grant, grant, sizeof(ul_sched_grant));
current_irv = irv_of_rv[grant->get_rv()%4];
harq_feedback = false;
Info("UL PID %d: Adaptive retx=%d, RV=%d, TBS=%d, MCS=%d\n", pid, current_tx_nb, get_rv(), grant->get_tbs(), grant->get_mcs());
generate_tx(tti_tx, NULL, ul);
} else {
Info("UL PID %d: Non-Adaptive retx=%d, RV=%d, TBS=%d, MCS=%d\n", pid, current_tx_nb, get_rv(), cur_grant.get_tbs(), cur_grant.get_mcs());
// HARQ entity requests a non-adaptive transmission
if (!harq_feedback) {
generate_tx(tti_tx, NULL, ul);
@ -231,12 +234,6 @@ void ul_harq_entity::ul_harq_process::generate_retx(uint32_t tti_tx, ul_sched_gr
}
}
void ul_harq_entity::ul_harq_process::generate_retx(uint32_t tti_tx, ul_buffer* ul)
{
generate_retx(tti_tx, NULL, ul);
}
// New transmission (Section 5.4.2.2)
void ul_harq_entity::ul_harq_process::generate_new_tx(uint32_t tti_tx, uint8_t *pdu_payload, bool is_msg3_, ul_sched_grant* ul_grant, ul_buffer* ul)
{
@ -249,6 +246,7 @@ void ul_harq_entity::ul_harq_process::generate_new_tx(uint32_t tti_tx, uint8_t *
current_tx_nb = 0;
current_irv = 0;
is_msg3 = is_msg3_;
Info("UL PID %d: New TX%s, RV=%d, TBS=%d, MCS=%d\n", pid, is_msg3?" for Msg3":"", get_rv(), cur_grant.get_tbs(), cur_grant.get_mcs());
generate_tx(tti_tx, pdu_payload, ul);
}
}
@ -264,12 +262,14 @@ void ul_harq_entity::ul_harq_process::generate_tx(uint32_t tti_tx, uint8_t *pdu_
tti_last_tx = tti_tx;
if (is_msg3) {
if (current_tx_nb == harq_entity->params_db->get_param(mac_params::HARQ_MAXMSG3TX)) {
Info("Maximum number of ReTX for Msg3 reached (%d). Discarting TB.\n", harq_entity->params_db->get_param(mac_params::HARQ_MAXMSG3TX));
Info("UL PID %d: Maximum number of ReTX for Msg3 reached (%d). Discarting TB.\n", pid,
harq_entity->params_db->get_param(mac_params::HARQ_MAXMSG3TX));
reset();
}
} else {
if (current_tx_nb == harq_entity->params_db->get_param(mac_params::HARQ_MAXTX)) {
Info("Maximum number of ReTX reached (%d). Discarting TB.\n", harq_entity->params_db->get_param(mac_params::HARQ_MAXTX));
Info("UL PID %d: Maximum number of ReTX reached (%d). Discarting TB.\n", pid,
harq_entity->params_db->get_param(mac_params::HARQ_MAXTX));
reset();
}
}

View File

@ -124,10 +124,11 @@ void setup_mac_phy_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, srslte::u
mac->set_param(srslte::ue::mac_params::HARQ_MAXMSG3TX,
sib2->rr_config_common_sib.rach_cnfg.max_harq_msg3_tx);
printf("Set RACH ConfigCommon: NofPreambles=%d, ResponseWindow=%d, ContentionResolutionTimer=%d ms\n",
printf("Set RACH ConfigCommon: NofPreambles=%d, ResponseWindow=%d, ContentionResolutionTimer=%d ms, MaxTrials=%d\n",
liblte_rrc_number_of_ra_preambles_num[sib2->rr_config_common_sib.rach_cnfg.num_ra_preambles],
liblte_rrc_ra_response_window_size_num[sib2->rr_config_common_sib.rach_cnfg.ra_resp_win_size],
liblte_rrc_mac_contention_resolution_timer_num[sib2->rr_config_common_sib.rach_cnfg.mac_con_res_timer]);
liblte_rrc_mac_contention_resolution_timer_num[sib2->rr_config_common_sib.rach_cnfg.mac_con_res_timer],
liblte_rrc_preamble_trans_max_num[sib2->rr_config_common_sib.rach_cnfg.preamble_trans_max]);
// PDSCH ConfigCommon
mac->set_param(srslte::ue::mac_params::PDSCH_RSPOWER,
@ -246,7 +247,7 @@ int main(int argc, char *argv[])
phy.init(&radio_uhd, &ttisync, &phy_log);
} else {
radio_uhd.init_agc();
radio_uhd.set_tx_rx_gain_offset(-10);
radio_uhd.set_tx_rx_gain_offset(0);
phy.init_agc(&radio_uhd, &ttisync, &phy_log);
}
// Init MAC
@ -330,7 +331,7 @@ int main(int argc, char *argv[])
}
break;
case CONNECT:
// Waint for Connection Setup
// Wait for Connection Setup
n = mac.recv_ccch_sdu(bit_msg.msg, LIBLTE_MAX_MSG_SIZE);
if (n > 0) {
printf("ConnSetup received %d bytes\n", n/8);

View File

@ -72,6 +72,9 @@ namespace ue {
uint32_t get_ncce() {
return ncce;
}
uint32_t get_mcs() {
return dl_dci.mcs_idx;
}
bool create_from_dci(srslte_dci_msg_t *msg, srslte_cell_t cell, uint32_t cfi, uint32_t sf_idx, uint32_t ncce_) {
ncce = ncce_;
if (srslte_dci_msg_to_dl_grant(msg, rnti, cell, cfi, sf_idx, &dl_dci, &grant)) {

View File

@ -161,6 +161,8 @@ private:
int sync_sfn();
void run_rx_tx_state();
ul_buffer* get_ul_buffer_adv(uint32_t tti);
float old_gain;
};
}

View File

@ -67,6 +67,9 @@ namespace ue {
uint32_t get_tbs() {
return grant.mcs.tbs;
}
uint32_t get_mcs() {
return ul_dci.mcs_idx;
}
uint32_t get_current_tx_nb() {
return current_tx_nb;
}

View File

@ -69,10 +69,11 @@ void dl_buffer::free_cell()
bool dl_buffer::recv_ue_sync(srslte_ue_sync_t *ue_sync, srslte_timestamp_t *rx_time)
{
bool ret = false;
if (signal_buffer) {
cf_t *sf_buffer = NULL;
sf_symbols_and_ce_done = false;
pdcch_llr_extracted = false;
if (signal_buffer) {
bzero(signal_buffer, sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
if (srslte_ue_sync_get_buffer(ue_sync, &sf_buffer) == 1) {
memcpy(signal_buffer, sf_buffer, sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
ready();
@ -202,6 +203,7 @@ bool dl_buffer::decode_data(dl_sched_grant *grant, srslte_softbuffer_rx_t *softb
grant->get_pdsch_cfg(tti%10, &ue_dl.pdsch_cfg);
if (ue_dl.pdsch_cfg.grant.mcs.mod > 0 && ue_dl.pdsch_cfg.grant.mcs.tbs >= 0) {
int ret = srslte_pdsch_decode_rnti(&ue_dl.pdsch, &ue_dl.pdsch_cfg, softbuffer, ue_dl.sf_symbols,
ue_dl.ce, 0, grant->get_rnti(), payload);

View File

@ -143,6 +143,10 @@ bool phy::send_prach(uint32_t preamble_idx, int allowed_subframe) {
bool phy::send_prach(uint32_t preamble_idx, int allowed_subframe, int target_power_dbm)
{
if (phy_state == RXTX) {
srslte_agc_lock(&ue_sync.agc, true);
old_gain = radio_handler->get_tx_gain();
radio_handler->set_tx_gain(0);
Info("Stopped AGC. Set TX gain to %.1f dB\n", 0);
return prach_buffer.prepare_to_send(preamble_idx, allowed_subframe, target_power_dbm);
}
return false;
@ -332,8 +336,8 @@ ul_buffer* phy::get_ul_buffer_adv(uint32_t tti)
dl_buffer* phy::get_dl_buffer(uint32_t tti)
{
if (tti + 6 < get_current_tti()) {
Warning("Warning access to PHY too late. Requested TTI=%d while PHY is in %d\n", tti, get_current_tti());
if (tti + 4 < get_current_tti()) {
Debug("Warning access to PHY too late. Requested TTI=%d while PHY is in %d\n", tti, get_current_tti());
}
return (dl_buffer*) dl_buffer_queue->get(tti);
}
@ -497,6 +501,9 @@ void phy::run_rx_tx_state()
// send prach if we have to
if (prach_buffer.is_ready_to_send(current_tti)) {
prach_buffer.send(radio_handler, cfo, last_rx_time);
radio_handler->set_tx_gain(old_gain);
srslte_agc_lock(&ue_sync.agc, false);
Info("Restoring AGC. Set TX gain to %.1f dB\n", old_gain);
}
if (sr_is_ready_to_send(current_tti+ul_buffer::tx_advance_sf)) {
get_ul_buffer_adv(current_tti)->generate_sr();

View File

@ -151,10 +151,19 @@ bool prach::send(radio *radio_handler, float cfo, srslte_timestamp_t rx_time)
// Correct CFO before transmission
srslte_cfo_correct(&cfo_h, buffer[preamble_idx], signal_buffer, cfo /srslte_symbol_sz(cell.nof_prb));
// Compute peak
float max = 0;
float *t = (float*) signal_buffer;
for (int i=0;i<2*len;i++) {
if (fabsf(t[i]) > max) {
max = fabsf(t[i]);
}
}
// transmit
radio_handler->tx(signal_buffer, len, tx_time);
Info("PRACH transmitted CFO: %f, preamble=%d, len=%d rx_time=%f, tx_time=%f\n",
cfo*15000, preamble_idx, len, rx_time.frac_secs, tx_time.frac_secs);
Info("PRACH transmitted CFO: %f, preamble=%d, len=%d rx_time=%f, tx_time=%f, PeakAmplitude=%.2f\n",
cfo*15000, preamble_idx, len, rx_time.frac_secs, tx_time.frac_secs, max);
preamble_idx = -1;
}

View File

@ -176,10 +176,6 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof
softbuffer,
grant->get_rnti(),
signal_buffer);
if (grant->get_rv() == 0) {
bzero(signal_buffer, 7680*sizeof(cf_t));
}
} else {
Info("Encoding PUCCH n_cce=%d, ack=%d\n", last_n_cce, uci_data.uci_ack);
@ -208,9 +204,10 @@ bool ul_buffer::send(srslte::radio* radio_handler, float time_adv_sec, float cfo
srslte_timestamp_copy(&tx_time, &rx_time);
srslte_timestamp_add(&tx_time, 0, tx_advance_sf*1e-3 - time_adv_sec);
// Correct CFO before transmission
srslte_cfo_correct(&ue_ul.cfo, signal_buffer, signal_buffer, cfo / srslte_symbol_sz(cell.nof_prb));
// Compute peak
#ifdef compute_peak
if (SRSLTE_VERBOSE_ISINFO()) {
float max = 0;
float *t = (float*) signal_buffer;
for (int i=0;i<2*SRSLTE_SF_LEN_PRB(cell.nof_prb);i++) {
@ -218,16 +215,15 @@ bool ul_buffer::send(srslte::radio* radio_handler, float time_adv_sec, float cfo
max = fabsf(t[i]);
}
}
}
#endif
Info("TX CFO: %f, len=%d, rx_time= %.6f tx_time = %.6f TA: %.1f us\n",
Info("TX CFO: %f, len=%d, rx_time= %.6f tx_time = %.6f TA: %.1f us PeakAmplitude=%.2f\n",
cfo*15000, SRSLTE_SF_LEN_PRB(cell.nof_prb),
srslte_timestamp_real(&rx_time),
srslte_timestamp_real(&tx_time), time_adv_sec*1000000);
srslte_timestamp_real(&tx_time), time_adv_sec*1000000, max);
// Correct CFO before transmission
srslte_cfo_correct(&ue_ul.cfo, signal_buffer, signal_buffer, cfo / srslte_symbol_sz(cell.nof_prb));
if (max > 1.0) {
srslte_vec_save_file((char*) "first_pusch", signal_buffer, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb));
}
radio_handler->tx(signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb), tx_time);

View File

@ -71,6 +71,8 @@ SRSLTE_API float cuhd_get_rx_gain_offset(void *h);
SRSLTE_API double cuhd_get_rx_gain(void *h);
SRSLTE_API double cuhd_get_tx_gain(void *h);
SRSLTE_API double cuhd_set_rx_freq(void *h,
double freq);

View File

@ -116,6 +116,7 @@ void srslte_agc_lock(srslte_agc_t *q, bool enable) {
}
void srslte_agc_process(srslte_agc_t *q, cf_t *signal, uint32_t len) {
if (!q->lock) {
float gain_db = 10*log10(q->gain);
float gain_uhd_db = 1.0;
//float gain_uhd = 1.0;
@ -181,3 +182,4 @@ void srslte_agc_process(srslte_agc_t *q, cf_t *signal, uint32_t len) {
}
}
}
}

View File

@ -237,6 +237,12 @@ double cuhd_get_rx_gain(void *h)
return handler->usrp->get_rx_gain();
}
double cuhd_get_tx_gain(void *h)
{
cuhd_handler *handler = static_cast < cuhd_handler * >(h);
return handler->usrp->get_tx_gain();
}
double cuhd_set_rx_freq(void *h, double freq)
{
cuhd_handler *handler = static_cast < cuhd_handler * >(h);

View File

@ -679,7 +679,8 @@ int dci_format1As_unpack(srslte_dci_msg_t *msg, srslte_ra_dl_dci_t *data, uint32
}
// rv version
srslte_bit_pack(data->rv_idx, &y, 2);
data->rv_idx = srslte_bit_unpack(&y, 2);
if (crc_is_crnti) {
// TPC not implemented
y++;

View File

@ -44,7 +44,7 @@
#define PHI_4 2 // PRACH phi parameter for format 4
#define MAX_ROOTS 838 // Max number of root sequences
#define PRACH_AMP 0.4
#define PRACH_AMP 1.0
/******************************************************
* Reference tables from 3GPP TS 36.211 v10.7.0

View File

@ -273,7 +273,7 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data,
}
if (q->normalize_en) {
float norm_factor = (float) q->cell.nof_prb/10;
float norm_factor = (float) 0.9*q->cell.nof_prb/5;
srslte_vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
}
ret = SRSLTE_SUCCESS;

View File

@ -81,7 +81,7 @@ uint32_t srslte_bit_unpack(uint8_t **bits, int nof_bits)
uint32_t value=0;
for(i=0; i<nof_bits; i++) {
value |= (*bits)[i] << (nof_bits-i-1);
value |= (uint32_t) (*bits)[i] << (nof_bits-i-1);
}
*bits += nof_bits;
return value;
@ -93,7 +93,7 @@ uint64_t srslte_bit_unpack_l(uint8_t **bits, int nof_bits)
uint64_t value=0;
for(i=0; i<nof_bits; i++) {
value |= (*bits)[i] << (nof_bits-i-1);
value |= (uint64_t) (*bits)[i] << (nof_bits-i-1);
}
*bits += nof_bits;
return value;