From 3c1c5a1508235fc2d0044f573c474fd8c99e5976 Mon Sep 17 00:00:00 2001 From: sharma Date: Mon, 4 Jun 2018 08:15:16 +0200 Subject: [PATCH] merge in changes from local copy which were made just prior to Orange Research Day demonstration --- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 27 +- openair1/PHY/LTE_TRANSPORT/edci.c | 6 +- openair1/PHY/LTE_TRANSPORT/mdci.h | 14 +- openair1/PHY/LTE_TRANSPORT/pucch.c | 6 +- openair1/SCHED/fapi_l1.c | 6 +- openair1/SCHED/phy_procedures_lte_eNb.c | 45 +- openair2/LAYER2/MAC/defs.h | 5 + openair2/LAYER2/MAC/eNB_scheduler.c | 5 +- openair2/LAYER2/MAC/eNB_scheduler_RA.c | 44 +- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 611 +++++++++++++++++- .../LAYER2/MAC/eNB_scheduler_primitives.c | 3 + openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 122 +++- openair2/RRC/LITE/MESSAGES/asn1_msg.c | 2 +- openair2/RRC/LITE/rrc_common.c | 2 +- openair2/RRC/LITE/rrc_eNB.c | 6 +- targets/ARCH/USRP/USERSPACE/LIB/Makefile.inc | 4 - targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 330 +++++++++- targets/RT/USER/lte-ru.c | 2 +- 18 files changed, 1140 insertions(+), 100 deletions(-) delete mode 100755 targets/ARCH/USRP/USERSPACE/LIB/Makefile.inc mode change 100755 => 100644 targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 9825f8a0f0..92784609e9 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -2696,18 +2696,19 @@ fill_mpdcch_dci0 (PHY_VARS_eNB * eNB, eNB_rxtx_proc_t * proc, mDCI_ALLOC_t * dci AssertFatal(1==0,"TDD not supported for eMTC yet\n"); } else { dci_alloc->dci_length = sizeof_DCI6_0A_5MHz_t; - ((DCI6_0A_10MHz_t *) dci_pdu)->type = 0; - ((DCI6_0A_10MHz_t *) dci_pdu)->hopping = hopping; - ((DCI6_0A_10MHz_t *) dci_pdu)->rballoc = rballoc; - ((DCI6_0A_10MHz_t *) dci_pdu)->mcs = mcs; - ((DCI6_0A_10MHz_t *) dci_pdu)->rep = rel13->pusch_repetition_levels; - ((DCI6_0A_10MHz_t *) dci_pdu)->harq_pid = rel13->harq_process; - ((DCI6_0A_10MHz_t *) dci_pdu)->ndi = ndi; - ((DCI6_0A_10MHz_t *) dci_pdu)->rv_idx = rel13->redudency_version; - ((DCI6_0A_10MHz_t *) dci_pdu)->TPC = TPC; - ((DCI6_0A_10MHz_t *) dci_pdu)->csi_req = cqi_req; - ((DCI6_0A_10MHz_t *) dci_pdu)->srs_req = rel13->srs_request; - ((DCI6_0A_10MHz_t *) dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number; + ((DCI6_0A_5MHz_t *) dci_pdu)->type = 0; + ((DCI6_0A_5MHz_t *) dci_pdu)->hopping = hopping; + ((DCI6_0A_5MHz_t *) dci_pdu)->rballoc = rballoc; + ((DCI6_0A_5MHz_t *) dci_pdu)->narrowband = narrowband; + ((DCI6_0A_5MHz_t *) dci_pdu)->mcs = mcs; + ((DCI6_0A_5MHz_t *) dci_pdu)->rep = rel13->pusch_repetition_levels; + ((DCI6_0A_5MHz_t *) dci_pdu)->harq_pid = rel13->harq_process; + ((DCI6_0A_5MHz_t *) dci_pdu)->ndi = ndi; + ((DCI6_0A_5MHz_t *) dci_pdu)->rv_idx = rel13->redudency_version; + ((DCI6_0A_5MHz_t *) dci_pdu)->TPC = TPC; + ((DCI6_0A_5MHz_t *) dci_pdu)->csi_req = cqi_req; + ((DCI6_0A_5MHz_t *) dci_pdu)->srs_req = rel13->srs_request; + ((DCI6_0A_5MHz_t *) dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number; } @@ -2721,6 +2722,7 @@ fill_mpdcch_dci0 (PHY_VARS_eNB * eNB, eNB_rxtx_proc_t * proc, mDCI_ALLOC_t * dci ((DCI6_0A_10MHz_t *) dci_pdu)->type = 0; ((DCI6_0A_10MHz_t *) dci_pdu)->hopping = hopping; ((DCI6_0A_10MHz_t *) dci_pdu)->rballoc = rballoc; + ((DCI6_0A_10MHz_t *) dci_pdu)->narrowband = narrowband; ((DCI6_0A_10MHz_t *) dci_pdu)->mcs = mcs; ((DCI6_0A_10MHz_t *) dci_pdu)->rep = rel13->pusch_repetition_levels; ((DCI6_0A_10MHz_t *) dci_pdu)->harq_pid = rel13->harq_process; @@ -2759,6 +2761,7 @@ fill_mpdcch_dci0 (PHY_VARS_eNB * eNB, eNB_rxtx_proc_t * proc, mDCI_ALLOC_t * dci ((DCI6_0A_20MHz_t *) dci_pdu)->type = 0; ((DCI6_0A_20MHz_t *) dci_pdu)->hopping = hopping; ((DCI6_0A_20MHz_t *) dci_pdu)->rballoc = rballoc; + ((DCI6_0A_20MHz_t *) dci_pdu)->narrowband = narrowband; ((DCI6_0A_20MHz_t *) dci_pdu)->mcs = rel13->mcs; ((DCI6_0A_20MHz_t *) dci_pdu)->rep = rel13->pusch_repetition_levels; ((DCI6_0A_20MHz_t *) dci_pdu)->harq_pid = rel13->harq_process; diff --git a/openair1/PHY/LTE_TRANSPORT/edci.c b/openair1/PHY/LTE_TRANSPORT/edci.c index fbc3adc7aa..546ff4a4f0 100755 --- a/openair1/PHY/LTE_TRANSPORT/edci.c +++ b/openair1/PHY/LTE_TRANSPORT/edci.c @@ -321,10 +321,12 @@ void generate_mdci_top(PHY_VARS_eNB * eNB, int frame, int subframe, int16_t amp, } else AssertFatal(1 == 0, "Illegal combination start_symbol %d, a_index %d\n", mdci->start_symbol, a_index); - LOG_I(PHY, "mdci %d, length %d: rnti %x, L %d, prb_pairs %d, ce_mode %d, i0 %d, ss %d ,coded_bits %d\n", + LOG_I(PHY, "mdci %d, length %d: rnti %x, L %d, prb_pairs %d, ce_mode %d, transmission type %s, i0 %d, ss %d ,coded_bits %d\n", i, mdci->dci_length,mdci->rnti, mdci->L, mdci->number_of_prb_pairs, - mdci->ce_mode, mdci->i0, mdci->start_symbol, + mdci->ce_mode, + mdci->transmission_type == 1? "dist" : "loc", + mdci->i0, mdci->start_symbol, coded_bits); // Note: We only have to run this every Nacc subframes during repetitions, data and scrambling are constant, but we do it for now to simplify during testing diff --git a/openair1/PHY/LTE_TRANSPORT/mdci.h b/openair1/PHY/LTE_TRANSPORT/mdci.h index 5068aa072c..6c2cb6b19e 100755 --- a/openair1/PHY/LTE_TRANSPORT/mdci.h +++ b/openair1/PHY/LTE_TRANSPORT/mdci.h @@ -56,7 +56,9 @@ struct DCI6_0A_5MHz { /// Modulation and Coding Scheme and Redundancy Version uint32_t mcs:4; /// RB Assignment (ceil(log2(floor(N_RB_UL/6))) + 5 bits) - uint32_t rballoc:7; + uint32_t rballoc:5; + /// narrowband index log2(floor(N_RB_DL/6))) bits + uint32_t narrowband:2; /// Hopping flag uint32_t hopping:1; /// type = 0 => DCI Format 0, type = 1 => DCI Format 1A @@ -90,7 +92,7 @@ struct DCI6_1A_5MHz { uint32_t mcs:4; /// Resource block assignment (assignment flag = 0 for 5 MHz, ceil(log2(floor(N_RB_DL/6)))+5) uint32_t rballoc:5; - /// narroband index log2(floor(N_RB_DL/6))) bits + /// narrowband index log2(floor(N_RB_DL/6))) bits uint32_t narrowband:2; /// Frequency hopping flag uint32_t hopping:1; @@ -125,7 +127,7 @@ struct DCI6_0A_10MHz { uint32_t mcs:4; /// RB Assignment (ceil(log2(floor(N_RB_UL/6))) + 5 bits) uint32_t rballoc:5; - /// narroband index log2(floor(N_RB_DL/6))) bits + /// narrowband index log2(floor(N_RB_DL/6))) bits uint32_t narrowband:3; /// Hopping flag uint32_t hopping:1; @@ -160,7 +162,7 @@ struct DCI6_1A_10MHz { uint32_t mcs:4; /// Resource block assignment uint32_t rballoc:5; - /// narroband index log2(floor(N_RB_DL/6))) bits + /// narrowband index log2(floor(N_RB_DL/6))) bits uint32_t narrowband:3; /// Frequency hopping flag uint32_t hopping:1; @@ -195,7 +197,7 @@ struct DCI6_0A_20MHz { uint32_t mcs:4; /// RB Assignment (ceil(log2(floor(N_RB_UL/6))) + 5 bits) uint32_t rballoc:5; - /// narroband index log2(floor(N_RB_DL/6))) bits + /// narrowband index log2(floor(N_RB_DL/6))) bits uint32_t narrowband:4; /// Hopping flag uint32_t hopping:1; @@ -230,7 +232,7 @@ struct DCI6_1A_20MHz { uint32_t mcs:4; /// Resource block assignment (assignment flag = 0 for 20 MHz, ceil(log2(floor(N_RB_DL/6)))+5) uint32_t rballoc:5; - /// narroband index log2(floor(N_RB_DL/6))) bits + /// narrowband index log2(floor(N_RB_DL/6))) bits uint32_t narrowband:4; /// Frequency hopping flag uint32_t hopping:1; diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c index d03ac16105..8b4e1d8556 100755 --- a/openair1/PHY/LTE_TRANSPORT/pucch.c +++ b/openair1/PHY/LTE_TRANSPORT/pucch.c @@ -2431,9 +2431,9 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, } // aa - LOG_I(PHY,"PUCCH 1a/b: SFN.SF %d.%d : stat %d,%d (pos %d)\n", + LOG_I(PHY,"PUCCH 1a/b: SFN.SF %d.%d : stat %d,%d (pos %d), n1_pucch %d\n", frame,subframe,stat_re,stat_im, - (subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])); + (subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe]),n1_pucch); LOG_D(PHY,"PUCCH 1a/b: SFN.SF %d.%d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",frame,subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres); eNB->pucch1ab_stats[UE_id][(subframe<<11) + 2*(eNB->pucch1ab_stats_cnt[UE_id][subframe])] = (stat_re); @@ -2448,7 +2448,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB, if (fmt==pucch_format1b) *(1+payload) = (stat_im<0) ? 1 : 2; } else { // insufficient energy on PUCCH so NAK - LOG_D(PHY,"PUCCH 1a/b: subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres); + LOG_I(PHY,"PUCCH 1a/b: subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d => DTX (n1_pucch %d)\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres,n1_pucch); *payload = 4; // DTX ((int16_t*)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[0] = (int16_t)(stat_re); ((int16_t*)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[1] = (int16_t)(stat_im); diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index fddea1a539..47fb36824e 100755 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -654,7 +654,11 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) if (ul_subframe<10) { // This means that there is an ul_subframe that can be configured here LOG_D(PHY,"NFAPI: Clearing dci allocations for potential UL\n"); - harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe); + + if (eNB->ulsch[i]->ue_type == 0) + harq_pid = subframe2harq_pid(fp,ul_frame,ul_subframe); + else + harq_pid = 0; // clear DCI allocation maps for new subframe diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index da5a5f9391..5657a15dba 100755 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -328,7 +328,13 @@ phy_procedures_eNB_TX (PHY_VARS_eNB * eNB, eNB_rxtx_proc_t * proc, relaying_type /* save old HARQ information needed for PHICH generation */ if (ul_subframe < 10) { // This means that there is a potential UL subframe that will be scheduled here for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - harq_pid = subframe2harq_pid (fp, ul_frame, ul_subframe); +#ifdef Rel14 + if (eNB->ulsch[i]->ue_type >0) harq_pid = 0; + else +#endif + harq_pid = subframe2harq_pid (fp, ul_frame, ul_subframe); + + if (eNB->ulsch[i]) { ulsch_harq = eNB->ulsch[i]->harq_processes[harq_pid]; @@ -410,6 +416,13 @@ phy_procedures_eNB_TX (PHY_VARS_eNB * eNB, eNB_rxtx_proc_t * proc, relaying_type harq_pid, dlsch0->harq_processes[harq_pid]->frame, dlsch0->harq_processes[harq_pid]->subframe); + /* + if (dlsch0->harq_processes[harq_pid]->frame > frame) { // remote stale DLSCH + LOG_W(PHY,"Removing stale DLSCH\n"); + dlsch0->active = 0; + dlsch0->harq_processes[harq_pid]->status = SCH_IDLE; + dlsch0->harq_mask &= ~(1 << harq_pid); + }*/ } if ((dlsch0->harq_processes[harq_pid]->status == ACTIVE) && (dlsch0->harq_processes[harq_pid]->frame == frame) && (dlsch0->harq_processes[harq_pid]->subframe == subframe)) pdsch_procedures (eNB, proc, harq_pid, dlsch0, dlsch1, &eNB->UE_stats[(uint32_t) UE_id], 0); @@ -525,7 +538,7 @@ prach_procedures (PHY_VARS_eNB * eNB, eNB->preamble_list_br[ind].preamble_rel8.rnti = 1 + subframe + (60*(eNB->prach_vars_br.first_frame[ce_level] % 40)); eNB->preamble_list_br[ind].instance_length = 0; //don't know exactly what this is eNB->preamble_list_br[ind].preamble_rel13.rach_resource_type = 1 + ce_level; // CE Level - LOG_D (PHY, "Filling NFAPI indication for RACH %d CELevel %d (mask %x) : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", + LOG_I (PHY, "Filling NFAPI indication for RACH %d CELevel %d (mask %x) : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n", ind, ce_level, prach_mask, @@ -541,7 +554,7 @@ prach_procedures (PHY_VARS_eNB * eNB, #endif { - if ((eNB->prach_energy_counter == 100) && (max_preamble_energy[0] > eNB->measurements.prach_I0 + 200)) { + if ((eNB->prach_energy_counter == 100) && (max_preamble_energy[0] > eNB->measurements.prach_I0 + 2000)) { LOG_D (PHY, "[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n", eNB->Mod_id, eNB->CC_id, frame, subframe, max_preamble[0], max_preamble_energy[0] / 10, max_preamble_energy[0] % 10, max_preamble_delay[0]); @@ -704,7 +717,7 @@ uci_procedures (PHY_VARS_eNB * eNB, eNB_rxtx_proc_t * proc) } case HARQ: if (fp->frame_type == FDD) { - LOG_D (PHY, "Frame %d Subframe %d Demodulating PUCCH (UCI %d) for ACK/NAK (uci->pucch_fmt %d,uci->type %d.uci->frame %d, uci->subframe %d): n1_pucch0 %d SR_payload %d\n", + LOG_I (PHY, "Frame %d Subframe %d Demodulating PUCCH (UCI %d) for ACK/NAK (uci->pucch_fmt %d,uci->type %d.uci->frame %d, uci->subframe %d): n1_pucch0 %d SR_payload %d\n", frame, subframe, i, uci->pucch_fmt, uci->type, uci->frame, uci->subframe, uci->n_pucch_1[0][0], SR_payload); metric[0] = rx_pucch (eNB, uci->pucch_fmt, i, uci->n_pucch_1[0][0], 0, //n2_pucch @@ -736,7 +749,7 @@ uci_procedures (PHY_VARS_eNB * eNB, eNB_rxtx_proc_t * proc) } - LOG_D (PHY, "[eNB %d][PDSCH %x] Frame %d subframe %d pucch1a (FDD) payload %d (metric %d)\n", eNB->Mod_id, uci->rnti, frame, subframe, pucch_b0b1[0][0], metric[0]); + LOG_I (PHY, "[eNB %d][PDSCH %x] Frame %d subframe %d pucch1a (FDD) payload %d (metric %d)\n", eNB->Mod_id, uci->rnti, frame, subframe, pucch_b0b1[0][0], metric[0]); uci->stat = metric[0]; fill_uci_harq_indication (eNB, uci, frame, subframe, pucch_b0b1[0], 0, 0xffff); @@ -1122,26 +1135,19 @@ pusch_procedures (PHY_VARS_eNB * eNB, eNB_rxtx_proc_t * proc) //compute the expected ULSCH RX power (for the stats) ulsch_harq->delta_TF = get_hundred_times_delta_IF_eNB (eNB, i, harq_pid, 0); // 0 means bw_factor is not considered - if (ulsch_harq->cqi_crc_status == 1) { -#ifdef DEBUG_PHY_PROC - //if (((frame%10) == 0) || (frame < 50)) - print_CQI (ulsch_harq->o, ulsch_harq->uci_format, 0, fp->N_RB_DL); -#endif - fill_ulsch_cqi_indication (eNB, frame, subframe, ulsch_harq, ulsch->rnti); - } if (ret == (1 + MAX_TURBO_ITERATIONS)) { T (T_ENB_PHY_ULSCH_UE_NACK, T_INT (eNB->Mod_id), T_INT (frame), T_INT (subframe), T_INT (ulsch->rnti), T_INT (harq_pid)); fill_crc_indication (eNB, i, frame, subframe, 1); // indicate NAK to MAC fill_rx_indication (eNB, i, frame, subframe); // indicate SDU to MAC - - LOG_I (PHY, "[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n", + + /*LOG_I (PHY, "[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n", eNB->Mod_id, harq_pid, frame, subframe, i, ulsch_harq->round - 1, ulsch->Mlimit, ulsch_harq->o_ACK[0], ulsch_harq->o_ACK[1]); dump_ulsch(eNB,frame,subframe,i); exit(-1); - + */ if (ulsch_harq->round >= 3) { ulsch_harq->status = SCH_IDLE; ulsch_harq->handled = 0; @@ -1190,6 +1196,15 @@ pusch_procedures (PHY_VARS_eNB * eNB, eNB_rxtx_proc_t * proc) LOG_D (PHY, "[eNB %d] Frame %d subframe %d: received ULSCH harq_pid %d for UE %d, ret = %d, CQI CRC Status %d, ACK %d,%d, ulsch_errors %d/%d\n", eNB->Mod_id, frame, subframe, harq_pid, i, ret, ulsch_harq->cqi_crc_status, ulsch_harq->o_ACK[0], ulsch_harq->o_ACK[1], eNB->UE_stats[i].ulsch_errors[harq_pid], eNB->UE_stats[i].ulsch_decoding_attempts[harq_pid][0]); + + if (ulsch_harq->cqi_crc_status == 1) { +#ifdef DEBUG_PHY_PROC + //if (((frame%10) == 0) || (frame < 50)) + print_CQI (ulsch_harq->o, ulsch_harq->uci_format, 0, fp->N_RB_DL); +#endif + + fill_ulsch_cqi_indication (eNB, frame, subframe, ulsch_harq, ulsch->rnti); + } } // if ((ulsch) && // (ulsch->rnti>0) && // (ulsch_harq->status == ACTIVE)) diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index 9eeb545325..6af0fd66ca 100755 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -650,6 +650,10 @@ typedef struct { uint8_t mcs_UL[8]; /// TBS from last UL scheduling uint8_t TBS_UL[8]; + /// CQI_req from last scheduling + uint8_t oldCQI_UL[8]; + /// TPC from last scheduling + uint8_t oldTPC_UL[8]; /// Flag to indicate UL has been scheduled at least once boolean_t ul_active; /// Flag to indicate UE has been configured (ACK from RRCConnectionSetup received) @@ -816,6 +820,7 @@ typedef struct { int32_t phr_received; uint8_t periodic_ri_received[NFAPI_CC_MAX]; uint8_t aperiodic_ri_received[NFAPI_CC_MAX]; + uint32_t pucch_tpc_accumulated[NFAPI_CC_MAX]; uint8_t pucch1_cqi_update[NFAPI_CC_MAX]; uint8_t pucch1_snr[NFAPI_CC_MAX]; uint8_t pucch2_cqi_update[NFAPI_CC_MAX]; diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 8286e2dfd8..b126bbd997 100755 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -533,7 +533,10 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame schedule_SR(module_idP,frameP,subframeP); // This schedules UCI_CSI in subframeP schedule_CSI(module_idP, frameP, subframeP); - +#ifdef Rel14 + // This schedules DLSCH in subframeP + schedule_ue_spec_br(module_idP,frameP,subframeP); +#endif // This schedules DLSCH in subframeP schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index 5b4cd7cc6b..312a915463 100755 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -264,7 +264,7 @@ generate_Msg2 (module_id_t module_idP, int CC_idP, frame_t frameP, sub_frame_t s dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; // imposed (9.1.5 in 213) for Type 2 Common search space - AssertFatal (cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, "cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); + AssertFatal (cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, "cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 @@ -348,7 +348,7 @@ generate_Msg2 (module_id_t module_idP, int CC_idP, frame_t frameP, sub_frame_t s dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc[CC_idP].p_eNB == 1) ? 0 : 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; @@ -356,8 +356,8 @@ generate_Msg2 (module_id_t module_idP, int CC_idP, frame_t frameP, sub_frame_t s dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize (cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize (cc[CC_idP].mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc[CC_idP].p_eNB == 1) ? 1 : 2; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; @@ -440,7 +440,7 @@ generate_Msg2 (module_id_t module_idP, int CC_idP, frame_t frameP, sub_frame_t s dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc[CC_idP].p_eNB == 1) ? 0 : 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; @@ -448,8 +448,8 @@ generate_Msg2 (module_id_t module_idP, int CC_idP, frame_t frameP, sub_frame_t s dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize (cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize (cc[CC_idP].mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc[CC_idP].p_eNB == 1) ? 1 : 2; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; @@ -568,7 +568,7 @@ generate_Msg4 (module_id_t module_idP, int CC_idP, frame_t frameP, sub_frame_t s // set HARQ process round to 0 for this UE - if (cc->tdd_Config) + if (cc[CC_idP].tdd_Config) RA_template->harq_pid = ((frameP * 10) + subframeP) % 10; else RA_template->harq_pid = ((frameP * 10) + subframeP) & 7; @@ -582,6 +582,7 @@ generate_Msg4 (module_id_t module_idP, int CC_idP, frame_t frameP, sub_frame_t s #ifdef Rel14 if (RA_template->rach_resource_type > 0) { + RA_template->harq_pid = 0; // Generate DCI + repetitions first // This uses an MPDCCH Type 2 allocation according to Section 9.1.5 36-213, Type2 common allocation according to Table 7.1-8 (36-213) // Parameters: @@ -622,7 +623,7 @@ generate_Msg4 (module_id_t module_idP, int CC_idP, frame_t frameP, sub_frame_t s dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = 1; // imposed (9.1.5 in 213) for Type 2 Common search space - AssertFatal (cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, "cc[CC_id].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); + AssertFatal (cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, "cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = cc[CC_idP].sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->startSymbolBR_r13; dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 @@ -710,7 +711,7 @@ generate_Msg4 (module_id_t module_idP, int CC_idP, frame_t frameP, sub_frame_t s dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc[CC_idP].p_eNB == 1) ? 0 : 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; @@ -718,8 +719,8 @@ generate_Msg4 (module_id_t module_idP, int CC_idP, frame_t frameP, sub_frame_t s dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize (cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize (cc[CC_idP].mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc[CC_idP].p_eNB == 1) ? 1 : 2; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; @@ -885,7 +886,7 @@ generate_Msg4 (module_id_t module_idP, int CC_idP, frame_t frameP, sub_frame_t s lcid = 0; // put HARQ process round to 0 - if (cc->tdd_Config) + if (cc[CC_idP].tdd_Config) RA_template->harq_pid = ((frameP * 10) + subframeP) % 10; else RA_template->harq_pid = ((frameP * 10) + subframeP) & 7; @@ -922,7 +923,7 @@ generate_Msg4 (module_id_t module_idP, int CC_idP, frame_t frameP, sub_frame_t s 0, // redundancy version 1, // transport_blocks 0, // transport_block_to_codeword_swap_flag (0) - (cc->p_eNB == 1) ? 0 : 1, // transmission_scheme + (cc[CC_idP].p_eNB == 1) ? 0 : 1, // transmission_scheme 1, // number of layers 1, // number of subbands //0, // codebook index @@ -931,7 +932,7 @@ generate_Msg4 (module_id_t module_idP, int CC_idP, frame_t frameP, sub_frame_t s 0, // delta_power_offset_index 0, // ngap 1, // NPRB = 3 like in DCI - (cc->p_eNB == 1) ? 1 : 2, // transmission mode + (cc[CC_idP].p_eNB == 1) ? 1 : 2, // transmission mode 1, // num_bf_prb_per_subband 1); // num_bf_vector LOG_D (MAC, "Filled DLSCH config, pdu number %d, non-dci pdu_index %d\n", dl_req->number_pdu, eNB->pdu_index[CC_idP]); @@ -1022,7 +1023,8 @@ check_Msg4_retransmission (module_id_t module_idP, int CC_idP, frame_t frameP, s dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; N_RB_DL = to_prb (cc[CC_idP].mib->message.dl_Bandwidth); - LOG_I (MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 for harq_pid %d was acknowledged (round %d)\n", module_idP, CC_idP, frameP, subframeP, RA_template->harq_pid, round); + LOG_I (MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 for harq_pid %d was acknowledged (round %d) => SFN %d.%d\n", module_idP, CC_idP, frameP, subframeP, RA_template->harq_pid, round, + RA_template->Msg4_frame,RA_template->Msg4_subframe); if (round != 8) { @@ -1031,6 +1033,10 @@ check_Msg4_retransmission (module_id_t module_idP, int CC_idP, frame_t frameP, s if ((RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) { AssertFatal (1 == 0, "Msg4 Retransmissions not handled yet for BL/CE UEs\n"); } + if (round > 0) { + cancel_ra_proc (module_idP, CC_idP, frameP, RA_template->rnti); + rrc_mac_remove_ue(module_idP,RA_template->rnti); + } } else #endif { @@ -1070,7 +1076,7 @@ check_Msg4_retransmission (module_id_t module_idP, int CC_idP, frame_t frameP, s round & 3, // redundancy version 1, // transport_blocks 0, // transport_block_to_codeword_swap_flag (0) - (cc->p_eNB == 1) ? 0 : 1, // transmission_scheme + (cc[CC_idP].p_eNB == 1) ? 0 : 1, // transmission_scheme 1, // number of layers 1, // number of subbands //0, // codebook index @@ -1079,7 +1085,7 @@ check_Msg4_retransmission (module_id_t module_idP, int CC_idP, frame_t frameP, s 0, // delta_power_offset_index 0, // ngap 1, // NPRB = 3 like in DCI - (cc->p_eNB == 1) ? 1 : 2, // transmission mode + (cc[CC_idP].p_eNB == 1) ? 1 : 2, // transmission mode 1, // num_bf_prb_per_subband 1); // num_bf_vector } else @@ -1137,7 +1143,7 @@ schedule_RA (module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) if (RA_template->RA_active == TRUE) { - LOG_I (MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA %d is active (generate RAR %d, generate_Msg4 %d, wait_ack_Msg4 %d, rnti %x)\n", + LOG_D (MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA %d is active (generate RAR %d, generate_Msg4 %d, wait_ack_Msg4 %d, rnti %x)\n", module_idP, frameP, subframeP, CC_id, i, RA_template->generate_rar, RA_template->generate_Msg4, RA_template->wait_ack_Msg4, RA_template->rnti); if (RA_template->generate_rar == 1) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 6ab6a2d858..5a553828d3 100755 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -645,7 +645,7 @@ schedule_ue_spec_br( harq_pid = ue_sched_ctl->harq_pid[CC_id]; round = ue_sched_ctl->round[CC_id]; UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti; - UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); + UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = mac_eNB_get_rrc_status(module_idP, rnti);x UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; @@ -1509,11 +1509,11 @@ schedule_ue_spec_br( //------------------------------------------------------------------------------ void schedule_ue_spec( - module_id_t module_idP, - frame_t frameP, - sub_frame_t subframeP, - int* mbsfn_flag -) + module_id_t module_idP, + frame_t frameP, + sub_frame_t subframeP, + int *mbsfn_flag + ) //------------------------------------------------------------------------------ { @@ -1646,6 +1646,8 @@ schedule_ue_spec( ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + if (UE_list->UE_template[CC_id][UE_id].rach_resource_type > 0) continue_flag=1; + if (rnti==NOT_A_RNTI) { LOG_D(MAC,"Cannot find rnti for UE_id %d (num_UEs %d)\n",UE_id,UE_list->num_UEs); continue_flag=1; @@ -1731,7 +1733,7 @@ schedule_ue_spec( UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; - if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_CONNECTED) continue; + sdu_length_total=0; num_sdus=0; @@ -2421,6 +2423,601 @@ schedule_ue_spec( } +#ifdef Rel14 +//------------------------------------------------------------------------------ +void +schedule_ue_spec_br( + module_id_t module_idP, + frame_t frameP, + sub_frame_t subframeP + ) { + int CC_id = 0,UE_id; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = eNB->common_channels; + UE_list_t *UE_list = &eNB->UE_list; + UE_TEMPLATE *UE_template; + UE_sched_ctrl *ue_sched_ctl; + int32_t tpc=1; + int rvseq[4] = {0,2,3,1}; + mac_rlc_status_resp_t rlc_status; + unsigned char header_len_dcch=0, header_len_dcch_tmp=0; + unsigned char header_len_dtch=0, header_len_dtch_tmp=0, header_len_dtch_last=0; + unsigned char ta_len=0; + unsigned char sdu_lcids[NB_RB_MAX],lcid,offset,num_sdus=0; + uint16_t TBS,j,sdu_lengths[NB_RB_MAX],rnti,padding=0,post_padding=0; + unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; + int round; + int ta_update; + uint16_t sdu_length_total = 0; + int mcs; + int32_t normalized_rx_power, target_rx_power; + + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_ul_config_request_pdu_t *ul_config_pdu; + nfapi_tx_request_pdu_t *TX_req; + nfapi_dl_config_request_body_t *dl_req; + nfapi_ul_config_request_body_t *ul_req; + + struct PRACH_ConfigSIB_v1310 *ext4_prach; + struct PUCCH_ConfigCommon_v1310 *ext4_pucch; + PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13; + struct N1PUCCH_AN_InfoList_r13 *pucch_N1PUCCH_AN_InfoList_r13; + PRACH_ParametersCE_r13_t *p[4] = { NULL, NULL, NULL, NULL }; + int pucchreps[4] = { 1, 1, 1, 1 }; + int n1pucchan[4] = { 0, 0, 0, 0 }; + uint32_t ackNAK_absSF; + int first_rb; + + dl_req = &eNB->DL_req[CC_id].dl_config_request_body; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + + if ((frameP&1) == 0) return; + + if (cc[CC_id].radioResourceConfigCommon_BR) { + + ext4_prach = cc[CC_id].radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310; + ext4_pucch = cc[CC_id].radioResourceConfigCommon_BR->ext4->pucch_ConfigCommon_v1310; + prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; + pucch_N1PUCCH_AN_InfoList_r13 = ext4_pucch->n1PUCCH_AN_InfoList_r13; + AssertFatal (prach_ParametersListCE_r13 != NULL, "prach_ParametersListCE_r13 is null\n"); + AssertFatal (pucch_N1PUCCH_AN_InfoList_r13 != NULL, "pucch_N1PUCCH_AN_InfoList_r13 is null\n"); + // check to verify CE-Level compatibility in SIB2_BR + AssertFatal (prach_ParametersListCE_r13->list.count == pucch_N1PUCCH_AN_InfoList_r13->list.count, "prach_ParametersListCE_r13->list.count!= pucch_N1PUCCH_AN_InfoList_r13->list.count\n"); + + switch (prach_ParametersListCE_r13->list.count) { + case 4: + p[3] = prach_ParametersListCE_r13->list.array[3]; + n1pucchan[3] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[3]; + AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level3 shouldn't be NULL\n"); + pucchreps[3] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level3_r13); + + case 3: + p[2] = prach_ParametersListCE_r13->list.array[2]; + n1pucchan[2] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[2]; + AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level2 shouldn't be NULL\n"); + pucchreps[2] = (int) (4 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level2_r13); + case 2: + p[1] = prach_ParametersListCE_r13->list.array[1]; + n1pucchan[1] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[1]; + AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level1 shouldn't be NULL\n"); + pucchreps[1] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level1_r13); + case 1: + p[0] = prach_ParametersListCE_r13->list.array[0]; + n1pucchan[0] = *pucch_N1PUCCH_AN_InfoList_r13->list.array[0]; + AssertFatal (ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13 != NULL, "pucch_NumRepetitionCE_Msg4_Level0 shouldn't be NULL\n"); + pucchreps[0] = (int) (1 << *ext4_pucch->pucch_NumRepetitionCE_Msg4_Level0_r13); + break; + default: + AssertFatal (1 == 0, "Illegal count for prach_ParametersListCE_r13 %d\n", prach_ParametersListCE_r13->list.count); + } + } + + for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) { + + int harq_pid = 0; + + rnti = UE_RNTI(module_idP,UE_id); + if (rnti==NOT_A_RNTI) continue; + + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + UE_template = &UE_list->UE_template[CC_id][UE_id]; + + if (UE_template->rach_resource_type == 0) continue; + uint8_t rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); + + if (rrc_status < RRC_CONNECTED) continue; + + round = ue_sched_ctl->round[CC_id][harq_pid]; + + AssertFatal (UE_template->physicalConfigDedicated != NULL, + "UE_template->physicalConfigDedicated is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, + "UE_template->physicalConfigDedicated->ext4 is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == EPDCCH_Config_r11__config_r11_PR_setup, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n"); + + EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0]; + + AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n"); + AssertFatal(epdcch_setconfig_r11->ext2!=NULL, "epdcch_setconfig_r11->ext2 is null\n"); + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13!=NULL, + "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13!=NULL, + "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present==EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup, + "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n"); + AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310!=NULL, + "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null"); + AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present==EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup, + "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n"); + + + // simple scheduler for 1 repetition, 1 HARQ + if (subframeP == 5) { // MPDCCH + + if (round == 8) { + rlc_status.bytes_in_buffer = 0; + // Now check RLC information to compute number of required RBs + // get maximum TBS size for RLC request + TBS = get_TBS_DL(9,6); + // check first for RLC data on DCCH + // add the length for all the control elements (timing adv, drx, etc) : header + payload + + if (ue_sched_ctl->ta_timer == 0) { + ta_update = ue_sched_ctl->ta_update; + /* if we send TA then set timer to not send it for a while */ + if (ta_update != 31) + ue_sched_ctl->ta_timer = 20; + /* reset ta_update */ + ue_sched_ctl->ta_update = 31; + } else { + ta_update = 31; + } + + ta_len = (ta_update != 31) ? 2 : 0; + + header_len_dcch = 2; // 2 bytes DCCH SDU subheader + + if ( TBS-ta_len-header_len_dcch > 0 ) { + LOG_I(MAC,"Calling mac_rlc_status_ind for DCCH\n"); + rlc_status = mac_rlc_status_ind( + module_idP, + rnti, + module_idP, + frameP, + subframeP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH, + (TBS-ta_len-header_len_dcch)); // transport block set size + + sdu_lengths[0]=0; + + if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit + LOG_I(MAC,"[eNB %d] Frame %d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + module_idP,frameP,CC_id,TBS-header_len_dcch); + sdu_lengths[0] = mac_rlc_data_req( + module_idP, + rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH, + TBS, //not used + (char *)&dlsch_buffer[0]); + + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), + T_INT(harq_pid), T_INT(DCCH), T_INT(sdu_lengths[0])); + + LOG_I(MAC,"[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n",module_idP,CC_id,sdu_lengths[0]); + sdu_length_total = sdu_lengths[0]; + sdu_lcids[0] = DCCH; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH]+=1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH]+=sdu_lengths[0]; + num_sdus = 1; + } else { + header_len_dcch = 0; + sdu_length_total = 0; + } + } + + // check for DCCH1 and update header information (assume 2 byte sub-header) + if (TBS-ta_len-header_len_dcch-sdu_length_total > 0 ) { + rlc_status = mac_rlc_status_ind( + module_idP, + rnti, + module_idP, + frameP, + subframeP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH+1, + (TBS-ta_len-header_len_dcch-sdu_length_total)); // transport block set size less allocations for timing advance and + // DCCH SDU + sdu_lengths[num_sdus] = 0; + + if (rlc_status.bytes_in_buffer > 0) { + LOG_I(MAC,"[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + module_idP,frameP,CC_id,TBS-header_len_dcch-sdu_length_total); + sdu_lengths[num_sdus] += mac_rlc_data_req( + module_idP, + rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + DCCH+1, + TBS, //not used + (char *)&dlsch_buffer[sdu_length_total]); + + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), + T_INT(harq_pid), T_INT(DCCH+1), T_INT(sdu_lengths[num_sdus])); + + sdu_lcids[num_sdus] = DCCH1; + sdu_length_total += sdu_lengths[num_sdus]; + header_len_dcch += 2; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1]+=1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1]+=sdu_lengths[num_sdus]; + num_sdus++; + } + } + + // assume the max dtch header size, and adjust it later + header_len_dtch=0; + header_len_dtch_last=0; // the header length of the last mac sdu + // lcid has to be sorted before the actual allocation (similar struct as ue_list). + for (lcid=NB_RB_MAX-1; lcid>=DTCH ; lcid--){ + // TBD: check if the lcid is active + + header_len_dtch+=3; + header_len_dtch_last=3; + LOG_D(MAC,"[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", + module_idP,frameP,lcid,TBS, + TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch); + + if (TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch > 0 ) { // NN: > 2 ? + rlc_status = mac_rlc_status_ind(module_idP, + rnti, + module_idP, + frameP, + subframeP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch); + + + if (rlc_status.bytes_in_buffer > 0) { + + LOG_I(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", + module_idP,frameP,TBS-header_len_dcch-sdu_length_total-header_len_dtch,lcid, header_len_dtch); + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, + rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS, //not used + (char*)&dlsch_buffer[sdu_length_total]); + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), + T_INT(harq_pid), T_INT(lcid), T_INT(sdu_lengths[num_sdus])); + + LOG_I(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",module_idP,sdu_lengths[num_sdus],lcid); + sdu_lcids[num_sdus] = lcid; + sdu_length_total += sdu_lengths[num_sdus]; + + if (sdu_lengths[num_sdus] < 128) { + header_len_dtch--; + header_len_dtch_last--; + } + num_sdus++; + } // no data for this LCID + else { + header_len_dtch-=3; + } + } // no TBS left + else { + header_len_dtch-=3; + break; + } + } + if (header_len_dtch == 0 ) + header_len_dtch_last= 0; + // there is at least one SDU + // if (num_sdus > 0 ){ + if ((sdu_length_total + header_len_dcch + header_len_dtch )> 0) { + + // Now compute number of required RBs for total sdu length + // Assume RAH format 2 + // adjust header lengths + header_len_dcch_tmp = header_len_dcch; + header_len_dtch_tmp = header_len_dtch; + if (header_len_dtch==0) { + header_len_dcch = (header_len_dcch >0) ? 1 : 0;//header_len_dcch; // remove length field + } else { + header_len_dtch_last-=1; // now use it to find how many bytes has to be removed for the last MAC SDU + header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last :header_len_dtch; // remove length field for the last SDU + } + + mcs = 9; + + // decrease mcs until TBS falls below required length + while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs>0)) { + mcs--; + TBS = get_TBS_DL(mcs,6); + } + + // if we have decreased too much or we don't have enough RBs, increase MCS + while (TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) { + mcs++; + TBS = get_TBS_DL(mcs,6); + } + + //#ifdef DEBUG_eNB_SCHEDULER + LOG_I(MAC,"[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", + module_idP,CC_id,mcs,TBS,6); + // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", + // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); + + + if ((TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len) <= 2) { + padding = (TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len); + post_padding = 0; + } else { + padding = 0; + + // adjust the header len + if (header_len_dtch==0) { + header_len_dcch = header_len_dcch_tmp; + } else { //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2))) + header_len_dtch = header_len_dtch_tmp; + } + + post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len ; // 1 is for the postpadding header + } + + + offset = generate_dlsch_header((unsigned char*)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], + num_sdus, //num_sdus + sdu_lengths, // + sdu_lcids, + 255, // no drx + ta_update, // timing advance + NULL, // contention res id + padding, + post_padding); + + + if (ta_update != 31) { + LOG_D(MAC, + "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n", + module_idP,frameP, UE_id, CC_id, sdu_length_total,num_sdus,sdu_lengths[0],sdu_lcids[0],offset, + ta_update,padding,post_padding,mcs,TBS,6,header_len_dcch,header_len_dtch); + } + + + + // cycle through SDUs and place in dlsch_buffer + memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset],dlsch_buffer,sdu_length_total); + // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); + + // fill remainder of DLSCH with random data + for (j=0; j<(TBS-sdu_length_total-offset); j++) { + UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset+sdu_length_total+j] = (char)(taus()&0xff); + } + + + if (opt_enabled == 1) { + trace_pdu(1, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], + TBS, module_idP, 3, UE_RNTI(module_idP,UE_id), + eNB->frame, eNB->subframe,0,0); + LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", + module_idP, CC_id, frameP, UE_RNTI(module_idP,UE_id), TBS); + } + + T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), + T_INT(harq_pid), T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS)); + + // do PUCCH power control + // this is the normalized RX power + + /* TODO: fix how we deal with power, unit is not dBm, it's special from nfapi */ + normalized_rx_power = ue_sched_ctl->pucch1_snr[CC_id]; + target_rx_power = 208; + + // this assumes accumulated tpc + // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out + int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame*10+UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe; + if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case + ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around + if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { + ue_sched_ctl->pucch1_cqi_update[CC_id] = 0; + + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame=frameP; + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe=subframeP; + + if (normalized_rx_power>(target_rx_power+4)) { + tpc = 0; //-1 + ue_sched_ctl->pucch_tpc_accumulated[CC_id]--; + } else if (normalized_rx_power<(target_rx_power-4)) { + tpc = 2; //+1 + ue_sched_ctl->pucch_tpc_accumulated[CC_id]++; + } else { + tpc = 1; //0 + } + + LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", + module_idP,frameP, subframeP,harq_pid,tpc, + ue_sched_ctl->pucch_tpc_accumulated[CC_id],normalized_rx_power,target_rx_power); + + } // Po_PUCCH has been updated + else { + tpc = 1; //0 + } // time to do TPC update + else { + tpc = 1; //0 + } + + // Toggle NDI in first round + UE_template->oldNDI[harq_pid] = 1-UE_template->oldNDI[harq_pid]; + ue_sched_ctl->round[CC_id][harq_pid] = 0; + round=0; + } + + } + + if (round < 8) { + // fill in MDPDCCH + memset ((void *) dl_config_pdu, 0, sizeof (nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu)); + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 11 : 10; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_narrow_band = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_prb_pairs = 6; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mpdcch_tansmission_type = epdcch_setconfig_r11->transmissionType_r11; + AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11!=NULL, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n"); + + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ecce_index = 0; // Note: this should be dynamic + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.aggregation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti_type = 4; // t-CRNTI + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.rnti = rnti; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.transmission_power = 6000; // 0dB + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.resource_block_coding = getRIV (6, 0, 6) | ((epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1)<<5); + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs = 9; // adjust according to size of RAR, 208 bits with N1A_PRB=3 + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels = 0; // fix to 4 for now + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version = rvseq[round&3]; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator = UE_template->oldNDI[harq_pid]; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_resource_offset = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.dci_subframe_repetition_number = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpc = 3; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index_length = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.downlink_assignment_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.allocate_prach_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.preamble_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.prach_mask_index = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.starting_ce_level = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.srs_request = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.antenna_ports_and_scrambling_identity = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.frequency_hopping_enabled_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.paging_direct_indication_differentiation_flag = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.direct_indication = 0; + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.total_dci_length_including_padding = 0; // this is not needed by OAI L1, but should be filled in + dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.number_of_tx_antenna_ports = 1; + dl_req->number_pdu++; + UE_template->mcs[harq_pid] = dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.mcs; + } + } + else if ((subframeP == 7)&&(round<8)) { // DLSCH + + int absSF = (frameP * 10) + subframeP; + + // Have to check that MPDCCH was generated + LOG_I (MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating DLSCH (ce_level %d RNTI %x)\n", + module_idP, CC_id, frameP, subframeP, UE_template->rach_resource_type - 1,rnti); + + first_rb = narrowband_to_first_rb (&cc[CC_id], epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1); + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset ((void *) dl_config_pdu, 0, sizeof (nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = rnti; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV (to_prb (cc[CC_id].mib->message.dl_Bandwidth), first_rb, 6); // check that this isn't getRIV(6,0,6) + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc[CC_id].p_eNB == 1) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize (cc[CC_id].mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc[CC_id].p_eNB == 1) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; + + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11; + + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = (UE_template->rach_resource_type < 3) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not SI message + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = (10 * frameP) + subframeP; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.drms_table_flag = 0; + dl_req->number_pdu++; + + // DL request + eNB->TX_req[CC_id].sfn_sf = (frameP << 4) + subframeP; + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; + TX_req->pdu_length = get_TBS_DL(UE_template->mcs[harq_pid], + 6); + TX_req->pdu_index = eNB->pdu_index[CC_id]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = TX_req->pdu_length; + TX_req->segments[0].segment_data = eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char) UE_id].payload[0]; + eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; + + ackNAK_absSF = absSF + 4; + ul_req = &eNB->UL_req_tmp[CC_id][ackNAK_absSF % 10].ul_config_request_body; + ul_config_pdu = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; + + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_ul_config_uci_harq_pdu)); + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.handle = 0; // don't know how to use this + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti = rnti; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.ue_type = (UE_template->rach_resource_type < 3) ? 1 : 2; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.empty_symbols = 0; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.total_number_of_repetitions = pucchreps[UE_template->rach_resource_type - 1]; + ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel13.repetition_number = 0; + + if (cc[CC_id].tdd_Config == NULL) { // FDD case + ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.n_pucch_1_0 = n1pucchan[UE_template->rach_resource_type - 1]; + // NOTE: How to fill in the rest of the n_pucch_1_0 information 213 Section 10.1.2.1 in the general case + // = N_ECCE_q + Delta_ARO + n1pucchan[ce_level] + // higher in the MPDCCH configuration, N_ECCE_q is hard-coded to 0, and harq resource offset to 0 => + // Delta_ARO = 0 from Table 10.1.2.1-1 + ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.harq_size = 1; // 1-bit ACK/NAK + ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.number_of_pucch_resources = 1; + } else { + AssertFatal (1 == 0, "PUCCH configuration for ACK/NAK not handled yet for TDD BL/CE case\n"); + } + ul_req->number_of_pdus++; + T (T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT (module_idP), T_INT (CC_id), T_INT (rnti), T_INT (frameP), T_INT (subframeP), + T_INT (0 /*harq_pid always 0? */ ), T_BUFFER (&eNB->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0], TX_req->pdu_length)); + + if (opt_enabled == 1) { + trace_pdu (1, (uint8_t *) eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char) UE_id].payload[0], TX_req->pdu_length , UE_id, 3, rnti, frameP, subframeP, 0, 0); + LOG_D (OPT, "[eNB %d][DLSCH] CC_id %d Frame %d trace pdu for rnti %x with size %d\n", module_idP, CC_id, frameP, rnti, TX_req->pdu_length ); + } + + } + } + +} +#endif //------------------------------------------------------------------------------ void fill_DLSCH_dci( diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index e44fb518d6..af623d2d9f 100755 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -3072,6 +3072,9 @@ void extract_harq(module_id_t mod_idP,int CC_idP,int UE_id,frame_t frameP,sub_fr uint8_t harq_pid = ((10*frameP) + subframeP + 10236)&7; + // use 1 HARQ proces of BL/CE UE for now + if (UE_list->UE_template[pCCid][UE_id].rach_resource_type > 0) harq_pid = 0; + switch (harq_indication_fdd->mode) { case 0: // Format 1a/b (10.1.2.1) AssertFatal(numCC==1,"numCC %d > 1, should not be using Format1a/b\n",numCC); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index a92c3419f9..becb125dd5 100755 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -107,7 +107,7 @@ void rx_sdu(const module_id_t enb_mod_idP, #ifdef Rel14 if (UE_list->UE_template[CC_idP][UE_id].rach_resource_type > 0) harq_pid=0; #endif - LOG_D(MAC,"[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP, UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], + LOG_I(MAC,"[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP, UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], current_rnti, UE_id,ul_cqi); AssertFatal(UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] < 8, @@ -129,7 +129,7 @@ void rx_sdu(const module_id_t enb_mod_idP, } } else { // we've got an error - LOG_D(MAC,"[eNB %d][PUSCH %d] CC_id %d ULSCH in error in round %d, ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP, + LOG_I(MAC,"[eNB %d][PUSCH %d] CC_id %d ULSCH in error in round %d, ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP, UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid],ul_cqi); // AssertFatal(1==0,"ulsch in error\n"); @@ -1284,6 +1284,8 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, nfapi_ul_config_request_body_t *ul_req_tmp = &eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body; // loop over all active UEs + if ((frameP&1) == 1) return; + for (UE_id=UE_list->head_ul; UE_id>=0; UE_id=UE_list->next_ul[UE_id]) { if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].rach_resource_type == 0) continue; @@ -1319,7 +1321,7 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->ul_total_buffer; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP]); - if (UE_is_to_be_scheduled(module_idP,CC_id,UE_id) > 0 || round > 0)// || ((frameP%10)==0)) + if ((UE_template->ul_SR >0 || round > 0 || status < RRC_CONNECTED)&&(subframeP==5)) // if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames { LOG_I(MAC,"[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n", @@ -1333,15 +1335,22 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, emtc_active[CC_id]=1; UE_template->ul_SR = 0; status = mac_eNB_get_rrc_status(module_idP,rnti); + + /* if (status < RRC_CONNECTED) cqi_req = 0; - else if (UE_sched_ctrl->cqi_req_timer>30) { + else if (UE_sched_ctrl->cqi_req_timer>300) { cqi_req = 1; UE_sched_ctrl->cqi_req_timer=0; + } else cqi_req = 0; + */ + cqi_req = 0; + UE_template->oldCQI_UL[harq_pid] = cqi_req; + //power control //compute the expected ULSCH RX power (for the stats) @@ -1370,6 +1379,9 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, tpc = 1; //0 } //tpc = 1; + + UE_template->oldTPC_UL[harq_pid] = tpc; + if (tpc!=1) { LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", module_idP,frameP,subframeP,harq_pid,tpc, @@ -1401,16 +1413,10 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), T_INT(0), T_INT(6), T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi)); - if (mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED) - LOG_D(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, TBS %d, harq_pid %d)\n", - module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,UE_template->mcs_UL[harq_pid], - 0,6, - UE_template->TBS_UL[harq_pid],harq_pid); - // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) //store for possible retransmission UE_template->nb_rb_ul[harq_pid] = 6; - UE_template->first_rb_ul[harq_pid] = narrowband_to_first_rb (cc, 2); + UE_sched_ctrl->ul_scheduled |= (1<head) @@ -1428,8 +1434,6 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, // save it for a potential retransmission UE_template->cshift[harq_pid] = cshift; - LOG_I(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL 6-0A MPDCCH for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", - harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP); AssertFatal (UE_template->physicalConfigDedicated != NULL, "UE_template->physicalConfigDedicated is null\n"); AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, @@ -1453,7 +1457,12 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null"); AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present==EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup, "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n"); - + + LOG_I(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL 6-0A MPDCCH for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d,UESS MPDCCH Narrowband %d\n", + harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,(int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1); + + UE_template->first_rb_ul[harq_pid] = narrowband_to_first_rb (cc, + epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1); hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_dci+eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_hi]; memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t)); @@ -1488,7 +1497,7 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, "epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n"); hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1-epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.redudency_version = 0; - hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid]; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = 0; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tpc = tpc; hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.csi_request = cqi_req; @@ -1504,8 +1513,9 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_dci++; - LOG_I(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", - harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP); + LOG_I(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d, UESS mpdcch narrowband %d\n", + harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP, + (int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1); fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], @@ -1553,6 +1563,84 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), T_INT(0), T_INT(6), T_INT(round)); + AssertFatal (UE_template->physicalConfigDedicated != NULL, + "UE_template->physicalConfigDedicated is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, + "UE_template->physicalConfigDedicated->ext4 is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == EPDCCH_Config_r11__config_r11_PR_setup, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n"); + AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n"); + EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0]; + AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n"); + AssertFatal(epdcch_setconfig_r11->ext2!=NULL, "epdcch_setconfig_r11->ext2 is null\n"); + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13!=NULL, + "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13!=NULL, + "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null"); + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present==EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup, + "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n"); + AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310!=NULL, + "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null"); + AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present==EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup, + "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n"); + + LOG_I(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL 6-0A MPDCCH for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d,UESS MPDCCH Narrowband %d\n", + harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,(int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1); + + UE_template->first_rb_ul[harq_pid] = narrowband_to_first_rb (cc, + epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1); + hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_dci+eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_hi]; + memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t)); + + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE; + hi_dci0_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu)); + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 5 : 4; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type > 1) ? 2 : 1; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_narrowband = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1; + + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_prb_pairs = 6; // checked above that it has to be this + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_transmission_type = epdcch_setconfig_r11->transmissionType_r11; // distibuted + + AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11!=NULL, + "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n"); + + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ecce_index = 0; // Note: this should be dynamic + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.aggreagation_level = 24; // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4 + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti_type = 4; // other + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti = rnti; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.transmission_power = 6000; // 0dB + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid]; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4; // adjust according to size of RAR, 208 bits with N1A_PRB=3 + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = 0; + AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13== + EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off, + "epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n"); + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1-epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.redudency_version = rvidx_tab[round&3]; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid]; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = harq_pid; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tpc = UE_template->oldTPC_UL[harq_pid]; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.csi_request = UE_template->oldCQI_UL[harq_pid]; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ul_inex = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dai_presence_flag = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dl_assignment_index = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.srs_request = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_subframe_repetition_number = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tcp_bitmap = 0; + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.total_dci_length_include_padding = 29; // hard-coded for 10 MHz + hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_tx_antenna_ports = 1; + + eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_dci++; + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus], cqi_req, cc, diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c index 984cf315b1..68f013e7db 100755 --- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c @@ -2503,7 +2503,7 @@ do_RRCConnectionSetup_BR( physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 18;//ue_context_pP->local_uid; if (carrier->sib1->tdd_Config == NULL) { // FDD - physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 5+(ue_context_pP->local_uid%10); // Isr = 5 (every 10 subframes, offset=2+UE_id mod3) + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 76+(ue_context_pP->local_uid%10); // Isr = 76 (every 80 subframes, offset=2+UE_id mod3) } else { switch (carrier->sib1->tdd_Config->subframeAssignment) { case 1: diff --git a/openair2/RRC/LITE/rrc_common.c b/openair2/RRC/LITE/rrc_common.c index 9ae9606127..736b16422b 100755 --- a/openair2/RRC/LITE/rrc_common.c +++ b/openair2/RRC/LITE/rrc_common.c @@ -332,7 +332,7 @@ rrc_rx_tx( // check for UL failure RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { - LOG_I(RRC,"SFN.SN %d.%d => release timer %d/%d\n",ctxt_pP->frame,ctxt_pP->subframe, + LOG_D(RRC,"SFN.SN %d.%d => release timer %d/%d\n",ctxt_pP->frame,ctxt_pP->subframe, ue_context_p->ue_context.ue_release_timer,ue_context_p->ue_context.ue_release_timer_thres); if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe==0)) { if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) { diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 22aff3299d..7b708b5673 100755 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -1154,7 +1154,7 @@ rrc_eNB_generate_RRCConnectionRelease( // set release timer ue_context_pP->ue_context.ue_release_timer=1; // remove UE after 10 frames after RRCConnectionRelease is triggered - ue_context_pP->ue_context.ue_release_timer_thres=100; + ue_context_pP->ue_context.ue_release_timer_thres=1000; LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCConnectionRelease (bytes %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), @@ -3890,8 +3890,8 @@ rrc_eNB_generate_RRCConnectionSetup( // activate release timer, if RRCSetupComplete not received after 10 frames, remove UE ue_context_pP->ue_context.ue_release_timer=1; - // remove UE after 10 frames after RRCConnectionRelease is triggered - ue_context_pP->ue_context.ue_release_timer_thres=100; + // remove UE after 100 frames after RRCConnectionRelease is triggered + ue_context_pP->ue_context.ue_release_timer_thres=1000; } diff --git a/targets/ARCH/USRP/USERSPACE/LIB/Makefile.inc b/targets/ARCH/USRP/USERSPACE/LIB/Makefile.inc deleted file mode 100755 index 631f2162bd..0000000000 --- a/targets/ARCH/USRP/USERSPACE/LIB/Makefile.inc +++ /dev/null @@ -1,4 +0,0 @@ -USRP_OBJ += $(OPENAIR_TARGETS)/ARCH/USRP/USERSPACE/LIB/usrp_lib.o -USRP_FILE_OBJ += $(OPENAIR_TARGETS)/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp -USRP_CFLAGS += -I$(OPENAIR_TARGETS)/ARCH/COMMON -I$(OPENAIR_TARGETS)/ARCH/USRP/USERSPACE/LIB/ -I$(OPENAIR_TARGETS)/COMMON - diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp old mode 100755 new mode 100644 index 14f4c9d756..8b62a8e698 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -270,11 +270,53 @@ static int sync_to_gps(openair0_device *device) return EXIT_SUCCESS; } +#if defined(USRP_REC_PLAY) +#include "usrp_lib.h" +static FILE *pFile = NULL; +int mmapfd = 0; +struct stat sb; +iqrec_t *ms_sample = NULL; // memory for all subframes +unsigned int nb_samples = 0; +unsigned int cur_samples = 0; +int64_t wrap_count = 0; +int64_t wrap_ts = 0; +unsigned int u_sf_mode = 0; // 1=record, 2=replay +unsigned int u_sf_record = 0; // record mode +unsigned int u_sf_replay = 0; // replay mode +char u_sf_filename[1024]; // subframes file path +unsigned int u_sf_max = DEF_NB_SF; // max number of recorded subframes +unsigned int u_sf_loops = DEF_SF_NB_LOOP; // number of loops in replay mode +unsigned int u_sf_read_delay = DEF_SF_DELAY_READ; // read delay in replay mode +unsigned int u_sf_write_delay = DEF_SF_DELAY_WRITE; // write delay in replay mode +char *tmp_filename[1]; // use an array of pointer (libconfig does not seems to work with char array yet) + +char config_opt_sf_file[] = CONFIG_OPT_SF_FILE; +char config_def_sf_file[] = DEF_SF_FILE; +char config_hlp_sf_file[] = CONFIG_HLP_SF_FILE; +char config_opt_sf_rec[] = CONFIG_OPT_SF_REC; +char config_hlp_sf_rec[] = CONFIG_HLP_SF_REC; +char config_opt_sf_rep[] = CONFIG_OPT_SF_REP; +char config_hlp_sf_rep[] = CONFIG_HLP_SF_REP; +char config_opt_sf_max[] = CONFIG_OPT_SF_MAX; +char config_hlp_sf_max[] = CONFIG_HLP_SF_MAX; +char config_opt_sf_loops[] = CONFIG_OPT_SF_LOOPS; +char config_hlp_sf_loops[] = CONFIG_HLP_SF_LOOPS; +char config_opt_sf_rdelay[] = CONFIG_OPT_SF_RDELAY; +char config_hlp_sf_rdelay[] = CONFIG_HLP_SF_RDELAY; +char config_opt_sf_wdelay[] = CONFIG_OPT_SF_WDELAY; +char config_hlp_sf_wdelay[] = CONFIG_HLP_SF_WDELAY; + +#endif + /*! \brief Called to start the USRP transceiver. Return 0 if OK, < 0 if error @param device pointer to the device structure specific to the RF hardware target */ static int trx_usrp_start(openair0_device *device) { +#if defined(USRP_REC_PLAY) + if (u_sf_mode != 2) { // not replay mode +#endif + usrp_state_t *s = (usrp_state_t*)device->priv; @@ -313,12 +355,21 @@ static int trx_usrp_start(openair0_device *device) { s->rx_count = 0; s->tx_count = 0; s->rx_timestamp = 0; +#if defined(USRP_REC_PLAY) + } +#endif return 0; } /*! \brief Terminate operation of the USRP transceiver -- free all associated resources * \param device the hardware to use */ static void trx_usrp_end(openair0_device *device) { +#if defined(USRP_REC_PLAY) // For some ugly reason, this can be called several times... + static int done = 0; + if (done == 1) return; + done = 1; + if (u_sf_mode != 2) { // not subframes replay +#endif usrp_state_t *s = (usrp_state_t*)device->priv; s->rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); @@ -326,7 +377,45 @@ static void trx_usrp_end(openair0_device *device) { s->tx_md.end_of_burst = true; s->tx_stream->send("", 0, s->tx_md); s->tx_md.end_of_burst = false; - +#if defined(USRP_REC_PLAY) + } +#endif +#if defined(USRP_REC_PLAY) + if (u_sf_mode == 1) { // subframes store + pFile = fopen (u_sf_filename,"wb+"); + if (pFile == NULL) { + std::cerr << "Cannot open " << u_sf_filename << std::endl; + } else { + unsigned int i = 0; + unsigned int modu = 0; + if ((modu = nb_samples % 10) != 0) { + nb_samples -= modu; // store entire number of frames + } + std::cerr << "Writing " << nb_samples << " subframes to " << u_sf_filename << " ..." << std::endl; + for (i = 0; i < nb_samples; i++) { + fwrite(ms_sample+i, sizeof(unsigned char), sizeof(iqrec_t), pFile); + } + fclose (pFile); + std::cerr << "File " << u_sf_filename << " closed." << std::endl; + } + } + if (u_sf_mode == 1) { // record + if (ms_sample != NULL) { + free((void*)ms_sample); + ms_sample = NULL; + } + } + if (u_sf_mode == 2) { // replay + if (ms_sample != MAP_FAILED) { + munmap(ms_sample, sb.st_size); + ms_sample = NULL; + } + if (mmapfd != 0) { + close(mmapfd); + mmapfd = 0; + } + } +#endif } /*! \brief Called to send samples to the USRP RF target @@ -339,6 +428,9 @@ static void trx_usrp_end(openair0_device *device) { */ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { int ret=0; +#if defined(USRP_REC_PLAY) + if (u_sf_mode != 2) { // not replay mode +#endif usrp_state_t *s = (usrp_state_t*)device->priv; int nsamps2; // aligned to upper 32 or 16 byte boundary @@ -405,6 +497,15 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, if (ret != nsamps) LOG_E(PHY,"[xmit] tx samples %d != %d\n",ret,nsamps); +#if defined(USRP_REC_PLAY) + } else { + struct timespec req; + req.tv_sec = 0; + req.tv_nsec = u_sf_write_delay * 1000; + nanosleep(&req, NULL); + ret = nsamps; + } +#endif return ret; } @@ -421,9 +522,12 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, * \returns the number of sample read */ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { - usrp_state_t *s = (usrp_state_t*)device->priv; - int samples_received=0,i,j; - int nsamps2; // aligned to upper 32 or 16 byte boundary + usrp_state_t *s = (usrp_state_t*)device->priv; + int samples_received=0,i,j; + int nsamps2; // aligned to upper 32 or 16 byte boundary +#if defined(USRP_REC_PLAY) + if (u_sf_mode != 2) { // not replay mode +#endif #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ nsamps2 = (nsamps+7)>>3; @@ -490,7 +594,45 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp s->rx_count += nsamps; s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate); *ptimestamp = s->rx_timestamp; - return samples_received; +#if defined (USRP_REC_PLAY) + } +#endif +#if defined(USRP_REC_PLAY) + if (u_sf_mode == 1) { // record mode + // Copy subframes to memory (later dump on a file) + if (nb_samples < u_sf_max) { + (ms_sample+nb_samples)->header = BELL_LABS_IQ_HEADER; + (ms_sample+nb_samples)->ts = *ptimestamp; + memcpy((ms_sample+nb_samples)->samples, buff[0], nsamps*4); + nb_samples++; + } + } else if (u_sf_mode == 2) { // replay mode + if (cur_samples == nb_samples) { + cur_samples = 0; + wrap_count++; + if (wrap_count == u_sf_loops) { + std::cerr << "USRP device terminating subframes replay mode after " << u_sf_loops << " loops." << std::endl; + return 0; // should make calling process exit + } + wrap_ts = wrap_count * (nb_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000)); + } + if (cur_samples < nb_samples) { + *ptimestamp = (ms_sample[0].ts + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000))) + wrap_ts; + if (cur_samples == 0) { + std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts + << " ts=" << *ptimestamp << std::endl; + } + memcpy(buff[0], &ms_sample[cur_samples].samples[0], nsamps*4); + cur_samples++; + } + struct timespec req; + req.tv_sec = 0; + req.tv_nsec = u_sf_read_delay * 1000; + nanosleep(&req, NULL); + return nsamps; + } +#endif + return samples_received; } /*! \brief Compares two variables within precision @@ -567,7 +709,6 @@ int trx_usrp_set_gains(openair0_device* device, usrp_state_t *s = (usrp_state_t*)device->priv; ::uhd::gain_range_t gain_range_tx = s->usrp->get_tx_gain_range(0); s->usrp->set_tx_gain(gain_range_tx.stop()-openair0_cfg[0].tx_gain[0]); - ::uhd::gain_range_t gain_range = s->usrp->get_rx_gain_range(0); // limit to maximum gain if (openair0_cfg[0].rx_gain[0]-openair0_cfg[0].rx_gain_offset[0] > gain_range.stop()) { @@ -685,12 +826,135 @@ int trx_usrp_reset_stats(openair0_device* device) { return(0); } +#if defined(USRP_REC_PLAY) +extern "C" { +/*! \brief Initializer for USRP record/playback config + * \param parameter array description + * \returns 0 on success + */ +int trx_usrp_recplay_config_init(paramdef_t *usrp_recplay_params) { + // --subframes-file + memcpy(usrp_recplay_params[0].optname, config_opt_sf_file, strlen(config_opt_sf_file)); + usrp_recplay_params[0].helpstr = config_hlp_sf_file; + usrp_recplay_params[0].paramflags=PARAMFLAG_NOFREE; + usrp_recplay_params[0].strptr=(char **)&tmp_filename[0]; + usrp_recplay_params[0].defstrval = NULL; + usrp_recplay_params[0].type=TYPE_STRING; + usrp_recplay_params[0].numelt=sizeof(u_sf_filename); + // --subframes-record + memcpy(usrp_recplay_params[1].optname, config_opt_sf_rec, strlen(config_opt_sf_rec)); + usrp_recplay_params[1].helpstr = config_hlp_sf_rec; + usrp_recplay_params[1].paramflags=PARAMFLAG_BOOL; + usrp_recplay_params[1].uptr=&u_sf_record; + usrp_recplay_params[1].defuintval=0; + usrp_recplay_params[1].type=TYPE_UINT; + usrp_recplay_params[1].numelt=0; + // --subframes-replay + memcpy(usrp_recplay_params[2].optname, config_opt_sf_rep, strlen(config_opt_sf_rep)); + usrp_recplay_params[2].helpstr = config_hlp_sf_rep; + usrp_recplay_params[2].paramflags=PARAMFLAG_BOOL; + usrp_recplay_params[2].uptr=&u_sf_replay; + usrp_recplay_params[2].defuintval=0; + usrp_recplay_params[2].type=TYPE_UINT; + usrp_recplay_params[2].numelt=0; + // --subframes-max + memcpy(usrp_recplay_params[3].optname, config_opt_sf_max, strlen(config_opt_sf_max)); + usrp_recplay_params[3].helpstr = config_hlp_sf_max; + usrp_recplay_params[3].paramflags=0; + usrp_recplay_params[3].uptr=&u_sf_max; + usrp_recplay_params[3].defuintval=DEF_NB_SF; + usrp_recplay_params[3].type=TYPE_UINT; + usrp_recplay_params[3].numelt=0; + // --subframes-loops + memcpy(usrp_recplay_params[4].optname, config_opt_sf_loops, strlen(config_opt_sf_loops)); + usrp_recplay_params[4].helpstr = config_hlp_sf_loops; + usrp_recplay_params[4].paramflags=0; + usrp_recplay_params[4].uptr=&u_sf_loops; + usrp_recplay_params[4].defuintval=DEF_SF_NB_LOOP; + usrp_recplay_params[4].type=TYPE_UINT; + usrp_recplay_params[4].numelt=0; + // --subframes-read-delay + memcpy(usrp_recplay_params[5].optname, config_opt_sf_rdelay, strlen(config_opt_sf_rdelay)); + usrp_recplay_params[5].helpstr = config_hlp_sf_rdelay; + usrp_recplay_params[5].paramflags=0; + usrp_recplay_params[5].uptr=&u_sf_read_delay; + usrp_recplay_params[5].defuintval=DEF_SF_DELAY_READ; + usrp_recplay_params[5].type=TYPE_UINT; + usrp_recplay_params[5].numelt=0; + // --subframes-write-delay + memcpy(usrp_recplay_params[6].optname, config_opt_sf_wdelay, strlen(config_opt_sf_wdelay)); + usrp_recplay_params[6].helpstr = config_hlp_sf_wdelay; + usrp_recplay_params[6].paramflags=0; + usrp_recplay_params[6].uptr=&u_sf_write_delay; + usrp_recplay_params[6].defuintval=DEF_SF_DELAY_WRITE; + usrp_recplay_params[6].type=TYPE_UINT; + usrp_recplay_params[6].numelt=0; + + return 0; // always ok +} +} +#endif + extern "C" { /*! \brief Initialize Openair USRP target. It returns 0 if OK * \param device the hardware to use * \param openair0_cfg RF frontend parameters set by application */ int device_init(openair0_device* device, openair0_config_t *openair0_cfg) { +#if defined(USRP_REC_PLAY) + paramdef_t usrp_recplay_params[7]; + // to check + static int done = 0; + if (done == 1) { + return 0; + } // prevent from multiple init + done = 1; + // end to check + memset(usrp_recplay_params, 0, 7*sizeof(paramdef_t)); + memset(&u_sf_filename[0], 0, 1024); + tmp_filename[0] = u_sf_filename; + if (trx_usrp_recplay_config_init(usrp_recplay_params) != 0) { + std::cerr << "USRP device record/replay mode configuration error exiting" << std::endl; + return -1; + } + config_process_cmdline(usrp_recplay_params,sizeof(usrp_recplay_params)/sizeof(paramdef_t),NULL); + + if (strlen(tmp_filename[0]) != 0) { + (void) strcpy(u_sf_filename, tmp_filename[0]); + } else { + (void) strcpy(u_sf_filename, DEF_SF_FILE); + } + + if (u_sf_replay == 1) u_sf_mode = 2; + if (u_sf_record == 1) u_sf_mode = 1; + + if (u_sf_mode == 2) { + // Replay subframes from from file + int bw_gain_adjust=0; + device->openair0_cfg = openair0_cfg; + device->type = USRP_B200_DEV; + openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; + bw_gain_adjust=1; + openair0_cfg[0].tx_sample_advance = 80; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + openair0_cfg[0].iq_txshift = 4;//shift + openair0_cfg[0].iq_rxrescale = 15;//rescale iqs + set_rx_gain_offset(&openair0_cfg[0],0,bw_gain_adjust); + device->priv = NULL; + device->trx_start_func = trx_usrp_start; + device->trx_write_func = trx_usrp_write; + device->trx_read_func = trx_usrp_read; + device->trx_get_stats_func = trx_usrp_get_stats; + device->trx_reset_stats_func = trx_usrp_reset_stats; + device->trx_end_func = trx_usrp_end; + device->trx_stop_func = trx_usrp_stop; + device->trx_set_freq_func = trx_usrp_set_freq; + device->trx_set_gains_func = trx_usrp_set_gains; + device->openair0_cfg = openair0_cfg; + std::cerr << "USRP device initialized in subframes replay mode for " << u_sf_loops << " loops." << std::endl; + } else { +#endif uhd::set_thread_priority_safe(1.0); usrp_state_t *s = (usrp_state_t*)calloc(sizeof(usrp_state_t),1); @@ -706,6 +970,11 @@ extern "C" { int vers=0,subvers=0,subsubvers=0; int bw_gain_adjust=0; +#if defined(USRP_REC_PLAY) + if (u_sf_mode == 1) { + std::cerr << "USRP device initialized in subframes record mode" << std::endl; + } +#endif sscanf(uhd::get_version_string().c_str(),"%d.%d.%d",&vers,&subvers,&subsubvers); LOG_I(PHY,"Checking for USRPs : UHD %s (%d.%d.%d)\n", uhd::get_version_string().c_str(),vers,subvers,subsubvers); @@ -743,7 +1012,9 @@ extern "C" { //s->usrp->set_master_clock_rate(usrp_master_clock); openair0_cfg[0].rx_gain_calib_table = calib_table_x310; - +#if defined(USRP_REC_PLAY) + std::cerr << "-- Using calibration table: calib_table_x310" << std::endl; // Bell Labs info +#endif switch ((int)openair0_cfg[0].sample_rate) { case 30720000: // from usrp_time_offset @@ -802,9 +1073,15 @@ extern "C" { if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) { openair0_cfg[0].rx_gain_calib_table = calib_table_b210; bw_gain_adjust=0; +#if defined(USRP_REC_PLAY) + std::cerr << "-- Using calibration table: calib_table_b210" << std::endl; // Bell Labs info +#endif } else { openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38; bw_gain_adjust=1; +#if defined(USRP_REC_PLAY) + std::cerr << "-- Using calibration table: calib_table_b210_38" << std::endl; // Bell Labs info +#endif } switch ((int)openair0_cfg[0].sample_rate) { @@ -966,6 +1243,45 @@ extern "C" { } } +#if defined(USRP_REC_PLAY) + } +#endif +#if defined(USRP_REC_PLAY) + if (u_sf_mode == 1) { // record mode + ms_sample = (iqrec_t*) malloc(u_sf_max * sizeof(iqrec_t)); + if (ms_sample == NULL) { + std::cerr<< "Memory allocation failed for subframe record or replay mode." << std::endl; + exit(-1); + } + memset(ms_sample, 0, u_sf_max * BELL_LABS_IQ_BYTES_PER_SF); + } + if (u_sf_mode == 2) { + // use mmap + mmapfd = open(u_sf_filename, O_RDONLY | O_LARGEFILE); + if (mmapfd != 0) { + fstat(mmapfd, &sb); + std::cerr << "Loading subframes using mmap() from " << u_sf_filename << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl; + ms_sample = (iqrec_t*) mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, mmapfd, 0); + if (ms_sample != MAP_FAILED) { + nb_samples = (sb.st_size / sizeof(iqrec_t)); + int aligned = (((unsigned long)ms_sample & 31) == 0)? 1:0; + std::cerr<< "Loaded "<< nb_samples << " subframes." << std::endl; + if (aligned == 0) { + std::cerr<< "mmap address is not 32 bytes aligned, exiting." << std::endl; + close(mmapfd); + exit(-1); + } + } else { + std::cerr << "Cannot mmap file, exiting." << std::endl; + close(mmapfd); + exit(-1); + } + } else { + std::cerr << "Cannot open " << u_sf_filename << " , exiting." << std::endl; + exit(-1); + } + } +#endif return 0; } } diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 54693f43c8..e1953751ea 100755 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1237,7 +1237,7 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { cfg->tx_freq[i] = (double)fp->dl_CarrierFreq; cfg->rx_freq[i] = (double)fp->ul_CarrierFreq; - cfg->tx_gain[i] = (double)fp->att_tx; + cfg->tx_gain[i] = 10.0;//(double)fp->att_tx; cfg->rx_gain[i] = ru->max_rxgain-(double)fp->att_rx; cfg->configFilename = rf_config_file;