/******************************************************************************* OpenAirInterface Copyright(c) 1999 - 2014 Eurecom OpenAirInterface is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenAirInterface is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenAirInterface.The full GNU General Public License is included in this distribution in the file called "COPYING". If not, see <http://www.gnu.org/licenses/>. Contact Information OpenAirInterface Admin: openair_admin@eurecom.fr OpenAirInterface Tech : openair_tech@eurecom.fr OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE *******************************************************************************/ /*! \file phy_procedures_lte_eNB.c * \brief Implementation of eNB procedures from 36.213 LTE specifications * \author R. Knopp, F. Kaltenberger, N. Nikaein * \date 2011 * \version 0.1 * \company Eurecom * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,navid.nikaein@eurecom.fr * \note * \warning */ #include "PHY/defs.h" #include "PHY/extern.h" #include "MAC_INTERFACE/defs.h" #include "MAC_INTERFACE/extern.h" #include "SCHED/defs.h" #include "SCHED/extern.h" #ifdef EMOS #include "SCHED/phy_procedures_emos.h" #endif //#define DEBUG_PHY_PROC (Already defined in cmake) //#define DEBUG_ULSCH //#ifdef OPENAIR2 #include "LAYER2/MAC/extern.h" #include "LAYER2/MAC/defs.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" //#endif #include "assertions.h" #include "msc.h" #if defined(ENABLE_ITTI) # include "intertask_interface.h" # if ENABLE_RAL # include "timer.h" # endif #endif //#define DIAG_PHY #define NS_PER_SLOT 500000 #define PUCCH 1 extern int exit_openair; //extern void do_OFDM_mod(mod_sym_t **txdataF, int32_t **txdata, uint32_t frame, uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms); unsigned char dlsch_input_buffer[2700] __attribute__ ((aligned(16))); int eNB_sync_buffer0[640*6] __attribute__ ((aligned(16))); int eNB_sync_buffer1[640*6] __attribute__ ((aligned(16))); int *eNB_sync_buffer[2] = {eNB_sync_buffer0, eNB_sync_buffer1}; extern uint16_t hundred_times_log10_NPRB[100]; unsigned int max_peak_val; int max_sect_id, max_sync_pos; //DCI_ALLOC_t dci_alloc[8]; #ifdef EMOS fifo_dump_emos_eNB emos_dump_eNB; #endif #if defined(SMBV) && !defined(EXMIMO) extern const char smbv_fname[]; extern unsigned short config_frames[4]; extern uint8_t smbv_frame_cnt; #endif #ifdef DIAG_PHY extern int rx_sig_fifo; #endif uint8_t is_SR_subframe(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,uint8_t sched_subframe) { const int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx; const int frame = phy_vars_eNB->proc[sched_subframe].frame_rx; LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking for SR TXOp(sr_ConfigIndex %d)\n", phy_vars_eNB->Mod_id,phy_vars_eNB->ulsch_eNB[UE_id]->rnti,frame,subframe, phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex); if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 4) { // 5 ms SR period if ((subframe%5) == phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex) return(1); } else if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 14) { // 10 ms SR period if (subframe==(phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex-5)) return(1); } else if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 34) { // 20 ms SR period if ((10*(frame&1)+subframe) == (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex-15)) return(1); } else if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 74) { // 40 ms SR period if ((10*(frame&3)+subframe) == (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex-35)) return(1); } else if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 154) { // 80 ms SR period if ((10*(frame&7)+subframe) == (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex-75)) return(1); } return(0); } int32_t add_ue(int16_t rnti, PHY_VARS_eNB *phy_vars_eNB) { uint8_t i; #ifdef DEBUG_PHY_PROC LOG_I(PHY,"[eNB %d/%d] Adding UE with rnti %x\n", phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, (uint16_t)rnti); #endif for (i=0; i<NUMBER_OF_UE_MAX; i++) { if ((phy_vars_eNB->dlsch_eNB[i]==NULL) || (phy_vars_eNB->ulsch_eNB[i]==NULL)) { MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed add ue %"PRIx16" (ENOMEM)", rnti); LOG_E(PHY,"Can't add UE, not enough memory allocated\n"); return(-1); } else { if (phy_vars_eNB->eNB_UE_stats[i].crnti==0) { MSC_LOG_EVENT(MSC_PHY_ENB, "0 Add ue %"PRIx16" ", rnti); LOG_I(PHY,"UE_id %d associated with rnti %x\n",i, (uint16_t)rnti); phy_vars_eNB->dlsch_eNB[i][0]->rnti = rnti; phy_vars_eNB->ulsch_eNB[i]->rnti = rnti; phy_vars_eNB->eNB_UE_stats[i].crnti = rnti; phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH1_below = 0; phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH1_above = (int32_t)pow(10.0,.1*(phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH+phy_vars_eNB->rx_total_gain_eNB_dB)); phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH = (int32_t)pow(10.0,.1*(phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH+phy_vars_eNB->rx_total_gain_eNB_dB)); LOG_I(PHY,"Initializing Po_PUCCH: p0_NominalPUCCH %d, gain %d => %d\n", phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH, phy_vars_eNB->rx_total_gain_eNB_dB, phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH); return(i); } } } return(-1); } int32_t remove_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB, uint8_t abstraction_flag) { uint8_t i; for (i=0; i<NUMBER_OF_UE_MAX; i++) { if ((phy_vars_eNB->dlsch_eNB[i]==NULL) || (phy_vars_eNB->ulsch_eNB[i]==NULL)) { MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (ENOMEM)", rnti); LOG_E(PHY,"Can't remove UE, not enough memory allocated\n"); return(-1); } else { if (phy_vars_eNB->eNB_UE_stats[i].crnti==rnti) { MSC_LOG_EVENT(MSC_PHY_ENB, "0 Removed ue %"PRIx16" ", rnti); #ifdef DEBUG_PHY_PROC LOG_I(PHY,"eNB %d removing UE %d with rnti %x\n",phy_vars_eNB->Mod_id,i,rnti); #endif //msg("[PHY] UE_id %d\n",i); clean_eNb_dlsch(phy_vars_eNB->dlsch_eNB[i][0], abstraction_flag); clean_eNb_ulsch(phy_vars_eNB->ulsch_eNB[i],abstraction_flag); //phy_vars_eNB->eNB_UE_stats[i].crnti = 0; memset(&phy_vars_eNB->eNB_UE_stats[i],0,sizeof(LTE_eNB_UE_stats)); // mac_exit_wrapper("Removing UE"); return(i); } } } MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (not found)", rnti); return(-1); } int8_t find_next_ue_index(PHY_VARS_eNB *phy_vars_eNB) { uint8_t i; for (i=0; i<NUMBER_OF_UE_MAX; i++) { if (phy_vars_eNB->eNB_UE_stats[i].crnti==0) { /*if ((phy_vars_eNB->dlsch_eNB[i]) && (phy_vars_eNB->dlsch_eNB[i][0]) && (phy_vars_eNB->dlsch_eNB[i][0]->rnti==0))*/ LOG_D(PHY,"Next free UE id is %d\n",i); return(i); } } return(-1); } int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16_t rnti, const int frame, const uint8_t subframe,uint8_t *harq_pid,uint8_t *round,const uint8_t ul_flag) { LTE_eNB_DLSCH_t *DLSCH_ptr; LTE_eNB_ULSCH_t *ULSCH_ptr; uint8_t ulsch_subframe,ulsch_frame; uint8_t i; int8_t UE_id = find_ue(rnti,PHY_vars_eNB_g[Mod_id][CC_id]); int sf1=(10*frame)+subframe,sf2,sfdiff,sfdiff_max=7; int first_proc_found=0; if (UE_id==-1) { LOG_D(PHY,"Cannot find UE with rnti %x (Mod_id %d, CC_id %d)\n",rnti, Mod_id, CC_id); *round=0; return(-1); } if (ul_flag == 0) {// this is a DL request DLSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->dlsch_eNB[(uint32_t)UE_id][0]; // set to no available process first *harq_pid = -1; for (i=0; i<DLSCH_ptr->Mdlharq; i++) { if (DLSCH_ptr->harq_processes[i]!=NULL) { if (DLSCH_ptr->harq_processes[i]->status != ACTIVE) { // store first inactive process if (first_proc_found == 0) { first_proc_found = 1; *harq_pid = i; *round = 0; LOG_D(PHY,"process %d is first free process\n",i); } else { LOG_D(PHY,"process %d is free\n",i); } } else { sf2 = (DLSCH_ptr->harq_processes[i]->frame*10) + DLSCH_ptr->harq_processes[i]->subframe; if (sf2<=sf1) sfdiff = sf1-sf2; else // this happens when wrapping around 1024 frame barrier sfdiff = 10240 + sf1-sf2; LOG_D(PHY,"process %d is active, round %d (waiting %d)\n",i,DLSCH_ptr->harq_processes[i]->round,sfdiff); if (sfdiff>sfdiff_max) { // this is an active process that is waiting longer than the others (and longer than 7 ms) sfdiff_max = sfdiff; *harq_pid = i; *round = DLSCH_ptr->harq_processes[i]->round; first_proc_found = 1; } } } else { // a process is not defined LOG_E(PHY,"[eNB %d] DLSCH process %d for rnti %x (UE_id %d) not allocated\n",Mod_id,i,rnti,UE_id); return(-1); } } LOG_D(PHY,"get_ue_active_harq_pid DL => Frame %d, Subframe %d : harq_pid %d\n", frame,subframe,*harq_pid); } else { // This is a UL request ULSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->ulsch_eNB[(uint32_t)UE_id]; ulsch_subframe = pdcch_alloc2ul_subframe(&PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms,subframe); ulsch_frame = pdcch_alloc2ul_frame(&PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms,frame,subframe); // Note this is for TDD configuration 3,4,5 only *harq_pid = subframe2harq_pid(&PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms, ulsch_frame, ulsch_subframe); *round = ULSCH_ptr->harq_processes[*harq_pid]->round; LOG_T(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d Checking HARQ, round %d\n",Mod_id,*harq_pid,frame,subframe,*round); } return(0); } int CCE_table[800]; void init_nCCE_table(void) { memset(CCE_table,0,800*sizeof(int)); } int get_nCCE_offset(const unsigned char L, const int nCCE, const int common_dci, const unsigned short rnti, const unsigned char subframe) { int search_space_free,m,nb_candidates = 0,l,i; unsigned int Yk; /* printf("CCE Allocation: "); for (i=0;i<nCCE;i++) printf("%d.",CCE_table[i]); printf("\n"); */ if (common_dci == 1) { // check CCE(0 ... L-1) nb_candidates = (L==4) ? 4 : 2; nb_candidates = min(nb_candidates,nCCE/L); for (m = nb_candidates-1 ; m >=0 ; m--) { search_space_free = 1; for (l=0; l<L; l++) { if (CCE_table[(m*L) + l] == 1) { search_space_free = 0; break; } } if (search_space_free == 1) { for (l=0; l<L; l++) CCE_table[(m*L)+l]=1; return(m*L); } } return(-1); } else { // Find first available in ue specific search space // according to procedure in Section 9.1.1 of 36.213 (v. 8.6) // compute Yk Yk = (unsigned int)rnti; for (i=0; i<=subframe; i++) Yk = (Yk*39827)%65537; Yk = Yk % (nCCE/L); switch (L) { case 1: case 2: nb_candidates = 6; break; case 4: case 8: nb_candidates = 2; break; default: DevParam(L, nCCE, rnti); break; } // LOG_I(PHY,"rnti %x, Yk = %d, nCCE %d (nCCE/L %d),nb_cand %d\n",rnti,Yk,nCCE,nCCE/L,nb_candidates); for (m = 0 ; m < nb_candidates ; m++) { search_space_free = 1; for (l=0; l<L; l++) { if (CCE_table[(((Yk+m)%(nCCE/L))*L) + l] == 1) { search_space_free = 0; break; } } if (search_space_free == 1) { for (l=0; l<L; l++) CCE_table[(((Yk+m)%(nCCE/L))*L)+l]=1; return(((Yk+m)%(nCCE/L))*L); } } return(-1); } } int16_t get_target_pusch_rx_power(const module_id_t module_idP, const uint8_t CC_id) { //return PHY_vars_eNB_g[module_idP][CC_id]->PHY_measurements_eNB[0].n0_power_tot_dBm; return PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.ul_power_control_config_common.p0_NominalPUSCH; } int16_t get_target_pucch_rx_power(const module_id_t module_idP, const uint8_t CC_id) { //return PHY_vars_eNB_g[module_idP][CC_id]->PHY_measurements_eNB[0].n0_power_tot_dBm; return PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH; } #ifdef EMOS void phy_procedures_emos_eNB_TX(unsigned char subframe, PHY_VARS_eNB *phy_vars_eNB) { } #endif /* void phy_procedures_eNB_S_TX(unsigned char next_slot,PHY_VARS_eNB *phy_vars_eNB,uint8_t abstraction_flag) { int sect_id = 0, aa; if (next_slot%2==0) { #ifdef DEBUG_PHY_PROC msg("[PHY][eNB %d] Frame %d, slot %d: Generating pilots for DL-S\n", phy_vars_eNB->Mod_id,phy_vars_eNB->frame,next_slot); #endif for (sect_id=0;sect_id<number_of_cards;sect_id++) { if (abstraction_flag == 0) { for (aa=0; aa<phy_vars_eNB->lte_frame_parms.nb_antennas_tx; aa++) { #ifdef IFFT_FPGA memset(&phy_vars_eNB->lte_eNB_common_vars.txdataF[sect_id][aa][next_slot*(phy_vars_eNB->lte_frame_parms.N_RB_DL*12)*(phy_vars_eNB->lte_frame_parms.symbols_per_tti>>1)], 0,(phy_vars_eNB->lte_frame_parms.N_RB_DL*12)*(phy_vars_eNB->lte_frame_parms.symbols_per_tti>>1)*sizeof(mod_sym_t)); #else memset(&phy_vars_eNB->lte_eNB_common_vars.txdataF[sect_id][aa][next_slot*phy_vars_eNB->lte_frame_parms.ofdm_symbol_size*(phy_vars_eNB->lte_frame_parms.symbols_per_tti>>1)], 0,phy_vars_eNB->lte_frame_parms.ofdm_symbol_size*(phy_vars_eNB->lte_frame_parms.symbols_per_tti>>1)*sizeof(mod_sym_t)); #endif } generate_pilots_slot(phy_vars_eNB, phy_vars_eNB->lte_eNB_common_vars.txdataF[sect_id], AMP, next_slot); msg("[PHY][eNB] Frame %d, subframe %d Generating PSS\n", phy_vars_eNB->frame,next_slot>>1); generate_pss(phy_vars_eNB->lte_eNB_common_vars.txdataF[sect_id], 4*AMP, &phy_vars_eNB->lte_frame_parms, 2, next_slot); } else { #ifdef PHY_ABSTRACTION generate_pss_emul(phy_vars_eNB,sect_id); #endif } } } } */ void phy_procedures_eNB_S_RX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_eNB,uint8_t abstraction_flag,relaying_type_t r_type) { UNUSED(r_type); // unsigned char sect_id=0; int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx; #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_S_RX(%d)\n", phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_rx, subframe); #endif // for (sect_id=0;sect_id<number_of_cards;sect_id++) { if (abstraction_flag == 0) { lte_eNB_I0_measurements(phy_vars_eNB, subframe, 0, phy_vars_eNB->first_run_I0_measurements); } #ifdef PHY_ABSTRACTION else { lte_eNB_I0_measurements_emul(phy_vars_eNB, 0); } #endif } #ifdef EMOS void phy_procedures_emos_eNB_RX(unsigned char subframe,PHY_VARS_eNB *phy_vars_eNB) { uint8_t aa; uint16_t last_subframe_emos; uint16_t pilot_pos1 = 3 - phy_vars_eNB->lte_frame_parms.Ncp, pilot_pos2 = 10 - 2*phy_vars_eNB->lte_frame_parms.Ncp; uint32_t bytes; last_subframe_emos=0; #ifdef EMOS_CHANNEL //if (last_slot%2==1) // this is for all UL subframes if (subframe==3) for (aa=0; aa<phy_vars_eNB->lte_frame_parms.nb_antennas_rx; aa++) { memcpy(&emos_dump_eNB.channel[aa][last_subframe_emos*2*phy_vars_eNB->lte_frame_parms.N_RB_UL*12], &phy_vars_eNB->lte_eNB_pusch_vars[0]->drs_ch_estimates[0][aa][phy_vars_eNB->lte_frame_parms.N_RB_UL*12*pilot_pos1], phy_vars_eNB->lte_frame_parms.N_RB_UL*12*sizeof(int)); memcpy(&emos_dump_eNB.channel[aa][(last_subframe_emos*2+1)*phy_vars_eNB->lte_frame_parms.N_RB_UL*12], &phy_vars_eNB->lte_eNB_pusch_vars[0]->drs_ch_estimates[0][aa][phy_vars_eNB->lte_frame_parms.N_RB_UL*12*pilot_pos2], phy_vars_eNB->lte_frame_parms.N_RB_UL*12*sizeof(int)); } #endif if (subframe==4) { emos_dump_eNB.timestamp = rt_get_time_ns(); emos_dump_eNB.frame_tx = phy_vars_eNB->proc[subframe].frame_rx; emos_dump_eNB.rx_total_gain_dB = phy_vars_eNB->rx_total_gain_eNB_dB; emos_dump_eNB.mimo_mode = phy_vars_eNB->transmission_mode[0]; memcpy(&emos_dump_eNB.PHY_measurements_eNB, &phy_vars_eNB->PHY_measurements_eNB[0], sizeof(PHY_MEASUREMENTS_eNB)); memcpy(&emos_dump_eNB.eNB_UE_stats[0],&phy_vars_eNB->eNB_UE_stats[0],NUMBER_OF_UE_MAX*sizeof(LTE_eNB_UE_stats)); bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, &emos_dump_eNB, sizeof(fifo_dump_emos_eNB)); //bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, "test", sizeof("test")); if (bytes!=sizeof(fifo_dump_emos_eNB)) { LOG_W(PHY,"[eNB %d] Frame %d, subframe %d, Problem writing EMOS data to FIFO (bytes=%d, size=%d)\n", phy_vars_eNB->Mod_id,phy_vars_eNB->proc[(subframe+1)%10].frame_rx, subframe,bytes,sizeof(fifo_dump_emos_eNB)); } else { if (phy_vars_eNB->proc[(subframe+1)%10].frame_tx%100==0) { LOG_I(PHY,"[eNB %d] Frame %d (%d), subframe %d, Writing %d bytes EMOS data to FIFO\n", phy_vars_eNB->Mod_id,phy_vars_eNB->proc[(subframe+1)%10].frame_rx, ((fifo_dump_emos_eNB*)&emos_dump_eNB)->frame_tx, subframe, bytes); } } } } #endif #ifndef OPENAIR2 void fill_dci(DCI_PDU *DCI_pdu, uint8_t sched_subframe, PHY_VARS_eNB *phy_vars_eNB) { int i; uint8_t cooperation_flag = phy_vars_eNB->cooperation_flag; uint8_t transmission_mode = phy_vars_eNB->transmission_mode[0]; uint32_t rballoc = 0x7FFF; uint32_t rballoc2 = 0x000F; int subframe = phy_vars_eNB->proc[sched_subframe].subframe_tx; /* uint32_t rand = taus(); if ((subframe==8) || (subframe==9) || (subframe==0)) rand = (rand%5)+5; else rand = (rand%4)+5; */ uint32_t bcch_pdu; uint64_t dlsch_pdu; DCI_pdu->Num_common_dci = 0; DCI_pdu->Num_ue_spec_dci=0; switch (subframe) { case 5: DCI_pdu->Num_common_dci = 1; DCI_pdu->dci_alloc[0].L = 2; DCI_pdu->dci_alloc[0].rnti = SI_RNTI; DCI_pdu->dci_alloc[0].format = format1A; DCI_pdu->dci_alloc[0].ra_flag = 0; switch (phy_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) { DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_1_5MHz_FDD_t; ((DCI1A_1_5MHz_FDD_t*)&bcch_pdu)->type = 1; ((DCI1A_1_5MHz_FDD_t*)&bcch_pdu)->vrb_type = 0; ((DCI1A_1_5MHz_FDD_t*)&bcch_pdu)->rballoc = computeRIV(25,10,3); ((DCI1A_1_5MHz_FDD_t*)&bcch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1; ((DCI1A_1_5MHz_FDD_t*)&bcch_pdu)->rv = 1; ((DCI1A_1_5MHz_FDD_t*)&bcch_pdu)->mcs = 1; ((DCI1A_1_5MHz_FDD_t*)&bcch_pdu)->harq_pid = 0; ((DCI1A_1_5MHz_FDD_t*)&bcch_pdu)->TPC = 1; // set to 3 PRB memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&bcch_pdu,sizeof(DCI1A_1_5MHz_TDD_1_6_t)); } else { DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; ((DCI1A_1_5MHz_TDD_1_6_t*)&bcch_pdu)->type = 1; ((DCI1A_1_5MHz_TDD_1_6_t*)&bcch_pdu)->vrb_type = 0; ((DCI1A_1_5MHz_TDD_1_6_t*)&bcch_pdu)->rballoc = computeRIV(25,10,3); ((DCI1A_1_5MHz_TDD_1_6_t*)&bcch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1; ((DCI1A_1_5MHz_TDD_1_6_t*)&bcch_pdu)->rv = 1; ((DCI1A_1_5MHz_TDD_1_6_t*)&bcch_pdu)->mcs = 1; ((DCI1A_1_5MHz_TDD_1_6_t*)&bcch_pdu)->harq_pid = 0; ((DCI1A_1_5MHz_TDD_1_6_t*)&bcch_pdu)->TPC = 1; // set to 3 PRB memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&bcch_pdu,sizeof(DCI1A_1_5MHz_TDD_1_6_t)); } break; case 25: default: if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) { DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_5MHz_FDD_t; ((DCI1A_5MHz_FDD_t*)&bcch_pdu)->type = 1; ((DCI1A_5MHz_FDD_t*)&bcch_pdu)->vrb_type = 0; ((DCI1A_5MHz_FDD_t*)&bcch_pdu)->rballoc = computeRIV(25,10,3); ((DCI1A_5MHz_FDD_t*)&bcch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1; ((DCI1A_5MHz_FDD_t*)&bcch_pdu)->rv = 1; ((DCI1A_5MHz_FDD_t*)&bcch_pdu)->mcs = 1; ((DCI1A_5MHz_FDD_t*)&bcch_pdu)->harq_pid = 0; ((DCI1A_5MHz_FDD_t*)&bcch_pdu)->TPC = 1; // set to 3 PRB memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&bcch_pdu,sizeof(DCI1A_5MHz_TDD_1_6_t)); } else { DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; ((DCI1A_5MHz_TDD_1_6_t*)&bcch_pdu)->type = 1; ((DCI1A_5MHz_TDD_1_6_t*)&bcch_pdu)->vrb_type = 0; ((DCI1A_5MHz_TDD_1_6_t*)&bcch_pdu)->rballoc = computeRIV(25,10,3); ((DCI1A_5MHz_TDD_1_6_t*)&bcch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1; ((DCI1A_5MHz_TDD_1_6_t*)&bcch_pdu)->rv = 1; ((DCI1A_5MHz_TDD_1_6_t*)&bcch_pdu)->mcs = 1; ((DCI1A_5MHz_TDD_1_6_t*)&bcch_pdu)->harq_pid = 0; ((DCI1A_5MHz_TDD_1_6_t*)&bcch_pdu)->TPC = 1; // set to 3 PRB memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&bcch_pdu,sizeof(DCI1A_5MHz_TDD_1_6_t)); } break; case 50: if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) { DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_10MHz_FDD_t; ((DCI1A_10MHz_FDD_t*)&bcch_pdu)->type = 1; ((DCI1A_10MHz_FDD_t*)&bcch_pdu)->vrb_type = 0; ((DCI1A_10MHz_FDD_t*)&bcch_pdu)->rballoc = computeRIV(25,10,3); ((DCI1A_10MHz_FDD_t*)&bcch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1; ((DCI1A_10MHz_FDD_t*)&bcch_pdu)->rv = 1; ((DCI1A_10MHz_FDD_t*)&bcch_pdu)->mcs = 1; ((DCI1A_10MHz_FDD_t*)&bcch_pdu)->harq_pid = 0; ((DCI1A_10MHz_FDD_t*)&bcch_pdu)->TPC = 1; // set to 3 PRB memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&bcch_pdu,sizeof(DCI1A_10MHz_TDD_1_6_t)); } else { DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; ((DCI1A_10MHz_TDD_1_6_t*)&bcch_pdu)->type = 1; ((DCI1A_10MHz_TDD_1_6_t*)&bcch_pdu)->vrb_type = 0; ((DCI1A_10MHz_TDD_1_6_t*)&bcch_pdu)->rballoc = computeRIV(25,10,3); ((DCI1A_10MHz_TDD_1_6_t*)&bcch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1; ((DCI1A_10MHz_TDD_1_6_t*)&bcch_pdu)->rv = 1; ((DCI1A_10MHz_TDD_1_6_t*)&bcch_pdu)->mcs = 1; ((DCI1A_10MHz_TDD_1_6_t*)&bcch_pdu)->harq_pid = 0; ((DCI1A_10MHz_TDD_1_6_t*)&bcch_pdu)->TPC = 1; // set to 3 PRB memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&bcch_pdu,sizeof(DCI1A_10MHz_TDD_1_6_t)); } break; case 100: if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) { DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_20MHz_FDD_t; ((DCI1A_20MHz_FDD_t*)&bcch_pdu)->type = 1; ((DCI1A_20MHz_FDD_t*)&bcch_pdu)->vrb_type = 0; ((DCI1A_20MHz_FDD_t*)&bcch_pdu)->rballoc = computeRIV(25,10,3); ((DCI1A_20MHz_FDD_t*)&bcch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1; ((DCI1A_20MHz_FDD_t*)&bcch_pdu)->rv = 1; ((DCI1A_20MHz_FDD_t*)&bcch_pdu)->mcs = 1; ((DCI1A_20MHz_FDD_t*)&bcch_pdu)->harq_pid = 0; ((DCI1A_20MHz_FDD_t*)&bcch_pdu)->TPC = 1; // set to 3 PRB memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&bcch_pdu,sizeof(DCI1A_20MHz_TDD_1_6_t)); } else { DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; ((DCI1A_20MHz_TDD_1_6_t*)&bcch_pdu)->type = 1; ((DCI1A_20MHz_TDD_1_6_t*)&bcch_pdu)->vrb_type = 0; ((DCI1A_20MHz_TDD_1_6_t*)&bcch_pdu)->rballoc = computeRIV(25,10,3); ((DCI1A_20MHz_TDD_1_6_t*)&bcch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1; ((DCI1A_20MHz_TDD_1_6_t*)&bcch_pdu)->rv = 1; ((DCI1A_20MHz_TDD_1_6_t*)&bcch_pdu)->mcs = 1; ((DCI1A_20MHz_TDD_1_6_t*)&bcch_pdu)->harq_pid = 0; ((DCI1A_20MHz_TDD_1_6_t*)&bcch_pdu)->TPC = 1; // set to 3 PRB memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&bcch_pdu,sizeof(DCI1A_20MHz_TDD_1_6_t)); } break; } case 6: /* DCI_pdu->Num_ue_spec_dci = 1; DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI2_5MHz_2A_M10PRB_TDD_t; DCI_pdu->dci_alloc[0].L = 2; DCI_pdu->dci_alloc[0].rnti = 0x1236; DCI_pdu->dci_alloc[0].format = format2_2A_M10PRB; DCI_pdu->dci_alloc[0].ra_flag = 0; DLSCH_alloc_pdu1.rballoc = 0x00ff; DLSCH_alloc_pdu1.TPC = 0; DLSCH_alloc_pdu1.dai = 0; DLSCH_alloc_pdu1.harq_pid = 0; DLSCH_alloc_pdu1.tb_swap = 0; DLSCH_alloc_pdu1.mcs1 = 0; DLSCH_alloc_pdu1.ndi1 = 1; DLSCH_alloc_pdu1.rv1 = 0; DLSCH_alloc_pdu1.tpmi = 0; memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&DLSCH_alloc_pdu1,sizeof(DCI2_5MHz_2A_M10PRB_TDD_t)); */ break; case 7: DCI_pdu->Num_ue_spec_dci = 1; DCI_pdu->dci_alloc[0].L = 2; DCI_pdu->dci_alloc[0].rnti = 0x1235; DCI_pdu->dci_alloc[0].format = format1; DCI_pdu->dci_alloc[0].ra_flag = 0; if (transmission_mode<3) { //user 1 switch (phy_vars_eNB->lte_frame_parms.N_RB_DL) { case 25: if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) { DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1_5MHz_FDD_t; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rballoc = rballoc; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->TPC = 0; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->harq_pid = 0; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs; //((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->frame%1024)%28); ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rv = 0; memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&dlsch_pdu,sizeof(DCI1_5MHz_TDD_t)); /* //user2 DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1_5MHz_TDD_t; DCI_pdu->dci_alloc[1].L = 2; DCI_pdu->dci_alloc[1].rnti = 0x1236; DCI_pdu->dci_alloc[1].format = format1; DCI_pdu->dci_alloc[1].ra_flag = 0; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rballoc = rballoc2; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->TPC = 0; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->dai = 0; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->harq_pid = 1; //((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->proc[subframe].frame%1024)%28); ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->ndi = 1; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rv = 0; memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&((DCI1_5MHz_FDD_t *)&dlsch_pdu)->,sizeof(DCI1_5MHz_TDD_t)); */ } else { DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1_5MHz_TDD_t; ((DCI1_5MHz_TDD_t *)&dlsch_pdu)->rballoc = rballoc; ((DCI1_5MHz_TDD_t *)&dlsch_pdu)->TPC = 0; ((DCI1_5MHz_TDD_t *)&dlsch_pdu)->dai = 0; ((DCI1_5MHz_TDD_t *)&dlsch_pdu)->harq_pid = 0; ((DCI1_5MHz_TDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs; //((DCI1_5MHz_TDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->frame%1024)%28); ((DCI1_5MHz_TDD_t *)&dlsch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1; ((DCI1_5MHz_TDD_t *)&dlsch_pdu)->rv = 0; memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&dlsch_pdu,sizeof(DCI1_5MHz_TDD_t)); /* //user2 DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1_5MHz_TDD_t; DCI_pdu->dci_alloc[1].L = 2; DCI_pdu->dci_alloc[1].rnti = 0x1236; DCI_pdu->dci_alloc[1].format = format1; DCI_pdu->dci_alloc[1].ra_flag = 0; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rballoc = rballoc2; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->TPC = 0; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->dai = 0; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->harq_pid = 1; //((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->proc[subframe].frame%1024)%28); ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->ndi = 1; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rv = 0; memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&((DCI1_5MHz_FDD_t *)&dlsch_pdu)->,sizeof(DCI1_5MHz_TDD_t)); */ } break; case 50: if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) { DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1_10MHz_FDD_t; ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->rballoc = rballoc; ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->TPC = 0; ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->harq_pid = 0; ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs; //((DCI1_10MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->frame%1024)%28); ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1; ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->rv = 0; memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&dlsch_pdu,sizeof(DCI1_10MHz_TDD_t)); /* //user2 DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1_10MHz_TDD_t; DCI_pdu->dci_alloc[1].L = 2; DCI_pdu->dci_alloc[1].rnti = 0x1236; DCI_pdu->dci_alloc[1].format = format1; DCI_pdu->dci_alloc[1].ra_flag = 0; ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->rballoc = rballoc2; ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->TPC = 0; ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->dai = 0; ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->harq_pid = 1; //((DCI1_10MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->proc[subframe].frame%1024)%28); ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs; ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->ndi = 1; ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->rv = 0; memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&((DCI1_10MHz_FDD_t *)&dlsch_pdu)->,sizeof(DCI1_10MHz_TDD_t)); */ } else { DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1_10MHz_TDD_t; ((DCI1_10MHz_TDD_t *)&dlsch_pdu)->rballoc = rballoc; ((DCI1_10MHz_TDD_t *)&dlsch_pdu)->TPC = 0; ((DCI1_10MHz_TDD_t *)&dlsch_pdu)->dai = 0; ((DCI1_10MHz_TDD_t *)&dlsch_pdu)->harq_pid = 0; ((DCI1_10MHz_TDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs; //((DCI1_10MHz_TDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->frame%1024)%28); ((DCI1_10MHz_TDD_t *)&dlsch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1; ((DCI1_10MHz_TDD_t *)&dlsch_pdu)->rv = 0; memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&dlsch_pdu,sizeof(DCI1_10MHz_TDD_t)); /* //user2 DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1_10MHz_TDD_t; DCI_pdu->dci_alloc[1].L = 2; DCI_pdu->dci_alloc[1].rnti = 0x1236; DCI_pdu->dci_alloc[1].format = format1; DCI_pdu->dci_alloc[1].ra_flag = 0; ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->rballoc = rballoc2; ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->TPC = 0; ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->dai = 0; ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->harq_pid = 1; //((DCI1_10MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->proc[subframe].frame%1024)%28); ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs; ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->ndi = 1; ((DCI1_10MHz_FDD_t *)&dlsch_pdu)->rv = 0; memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&((DCI1_10MHz_FDD_t *)&dlsch_pdu)->,sizeof(DCI1_10MHz_TDD_t)); */ } break; case 100: if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) { DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1_5MHz_FDD_t; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rballoc = rballoc; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->TPC = 0; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->harq_pid = 0; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs; //((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->frame%1024)%28); ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rv = 0; memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&dlsch_pdu,sizeof(DCI1_5MHz_TDD_t)); /* //user2 DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1_5MHz_TDD_t; DCI_pdu->dci_alloc[1].L = 2; DCI_pdu->dci_alloc[1].rnti = 0x1236; DCI_pdu->dci_alloc[1].format = format1; DCI_pdu->dci_alloc[1].ra_flag = 0; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rballoc = rballoc2; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->TPC = 0; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->dai = 0; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->harq_pid = 1; //((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->proc[subframe].frame%1024)%28); ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->ndi = 1; ((DCI1_5MHz_FDD_t *)&dlsch_pdu)->rv = 0; memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&((DCI1_5MHz_FDD_t *)&dlsch_pdu)->,sizeof(DCI1_5MHz_TDD_t)); */ } else { DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1_20MHz_TDD_t; ((DCI1_20MHz_TDD_t *)&dlsch_pdu)->rballoc = rballoc; ((DCI1_20MHz_TDD_t *)&dlsch_pdu)->TPC = 0; ((DCI1_20MHz_TDD_t *)&dlsch_pdu)->dai = 0; ((DCI1_20MHz_TDD_t *)&dlsch_pdu)->harq_pid = 0; ((DCI1_20MHz_TDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs; //((DCI1_20MHz_TDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->frame%1024)%28); ((DCI1_20MHz_TDD_t *)&dlsch_pdu)->ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1; ((DCI1_20MHz_TDD_t *)&dlsch_pdu)->rv = 0; memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&dlsch_pdu,sizeof(DCI1_20MHz_TDD_t)); /* //user2 DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1_20MHz_TDD_t; DCI_pdu->dci_alloc[1].L = 2; DCI_pdu->dci_alloc[1].rnti = 0x1236; DCI_pdu->dci_alloc[1].format = format1; DCI_pdu->dci_alloc[1].ra_flag = 0; ((DCI1_20MHz_FDD_t *)&dlsch_pdu)->rballoc = rballoc2; ((DCI1_20MHz_FDD_t *)&dlsch_pdu)->TPC = 0; ((DCI1_20MHz_FDD_t *)&dlsch_pdu)->dai = 0; ((DCI1_20MHz_FDD_t *)&dlsch_pdu)->harq_pid = 1; //((DCI1_20MHz_FDD_t *)&dlsch_pdu)->mcs = (unsigned char) ((phy_vars_eNB->proc[subframe].frame%1024)%28); ((DCI1_20MHz_FDD_t *)&dlsch_pdu)->mcs = openair_daq_vars.target_ue_dl_mcs; ((DCI1_20MHz_FDD_t *)&dlsch_pdu)->ndi = 1; ((DCI1_20MHz_FDD_t *)&dlsch_pdu)->rv = 0; memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&((DCI1_20MHz_FDD_t *)&dlsch_pdu)->,sizeof(DCI1_5MHz_TDD_t)); */ } break; } } else if (transmission_mode==5) { DCI_pdu->Num_ue_spec_dci = 2; // user 1 DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t; DCI_pdu->dci_alloc[0].L = 3; DCI_pdu->dci_alloc[0].rnti = 0x1235; DCI_pdu->dci_alloc[0].format = format1E_2A_M10PRB; DCI_pdu->dci_alloc[0].ra_flag = 0; DLSCH_alloc_pdu1E.tpmi = 5; //5=use feedback DLSCH_alloc_pdu1E.rv = 0; DLSCH_alloc_pdu1E.ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1; //DLSCH_alloc_pdu1E.mcs = cqi_to_mcs[phy_vars_eNB->eNB_UE_stats->DL_cqi[0]]; //DLSCH_alloc_pdu1E.mcs = (unsigned char) (taus()%28); DLSCH_alloc_pdu1E.mcs = openair_daq_vars.target_ue_dl_mcs; //DLSCH_alloc_pdu1E.mcs = (unsigned char) ((phy_vars_eNB->proc[subframe].frame%1024)%28); phy_vars_eNB->eNB_UE_stats[0].dlsch_mcs1 = DLSCH_alloc_pdu1E.mcs; DLSCH_alloc_pdu1E.harq_pid = 0; DLSCH_alloc_pdu1E.dai = 0; DLSCH_alloc_pdu1E.TPC = 0; DLSCH_alloc_pdu1E.rballoc = openair_daq_vars.ue_dl_rb_alloc; DLSCH_alloc_pdu1E.rah = 0; DLSCH_alloc_pdu1E.dl_power_off = 0; //0=second user present memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&DLSCH_alloc_pdu1E,sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); //user 2 DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t; DCI_pdu->dci_alloc[1].L = 0; DCI_pdu->dci_alloc[1].rnti = 0x1236; DCI_pdu->dci_alloc[1].format = format1E_2A_M10PRB; DCI_pdu->dci_alloc[1].ra_flag = 0; //DLSCH_alloc_pdu1E.mcs = openair_daq_vars.target_ue_dl_mcs; //DLSCH_alloc_pdu1E.mcs = (unsigned char) (taus()%28); //DLSCH_alloc_pdu1E.mcs = (unsigned char) ((phy_vars_eNB->frame%1024)%28); DLSCH_alloc_pdu1E.mcs = (unsigned char) (((phy_vars_eNB->proc[sched_subframe].frame_tx%1024)/3)%28); phy_vars_eNB->eNB_UE_stats[1].dlsch_mcs1 = DLSCH_alloc_pdu1E.mcs; memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&DLSCH_alloc_pdu1E,sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); // set the precoder of the second UE orthogonal to the first phy_vars_eNB->eNB_UE_stats[1].DL_pmi_single = (phy_vars_eNB->eNB_UE_stats[0].DL_pmi_single ^ 0x1555); } break; /* case 8: DCI_pdu->Num_common_dci = 1; DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; DCI_pdu->dci_alloc[0].L = 2; DCI_pdu->dci_alloc[0].rnti = 0xbeef; DCI_pdu->dci_alloc[0].format = format1A; DCI_pdu->dci_alloc[0].ra_flag = 1; RA_alloc_pdu.type = 1; RA_alloc_pdu.vrb_type = 0; RA_alloc_pdu.rballoc = computeRIV(25,12,3); RA_alloc_pdu.ndi = 1; RA_alloc_pdu.rv = 1; RA_alloc_pdu.mcs = 4; RA_alloc_pdu.harq_pid = 0; RA_alloc_pdu.TPC = 1; memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&RA_alloc_pdu,sizeof(DCI1A_5MHz_TDD_1_6_t)); break; */ case 9: DCI_pdu->Num_ue_spec_dci = 1; //user 1 if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI0_5MHz_FDD_t ; else DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI0_5MHz_TDD_1_6_t ; DCI_pdu->dci_alloc[0].L = 2; DCI_pdu->dci_alloc[0].rnti = 0x1235; DCI_pdu->dci_alloc[0].format = format0; DCI_pdu->dci_alloc[0].ra_flag = 0; UL_alloc_pdu.type = 0; UL_alloc_pdu.hopping = 0; UL_alloc_pdu.rballoc = computeRIV(25,2,openair_daq_vars.ue_ul_nb_rb); UL_alloc_pdu.mcs = openair_daq_vars.target_ue_ul_mcs; UL_alloc_pdu.ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1; UL_alloc_pdu.TPC = 0; UL_alloc_pdu.cshift = 0; UL_alloc_pdu.dai = 0; UL_alloc_pdu.cqi_req = 1; memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&UL_alloc_pdu,sizeof(DCI0_5MHz_TDD_1_6_t)); // user 2 /* DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI0_5MHz_TDD_1_6_t ; DCI_pdu->dci_alloc[1].L = 2; DCI_pdu->dci_alloc[1].rnti = 0x1236; DCI_pdu->dci_alloc[1].format = format0; DCI_pdu->dci_alloc[1].ra_flag = 0; UL_alloc_pdu.type = 0; UL_alloc_pdu.hopping = 0; if (cooperation_flag==0) UL_alloc_pdu.rballoc = computeRIV(25,2+openair_daq_vars.ue_ul_nb_rb,openair_daq_vars.ue_ul_nb_rb); else UL_alloc_pdu.rballoc = computeRIV(25,0,openair_daq_vars.ue_ul_nb_rb); UL_alloc_pdu.mcs = openair_daq_vars.target_ue_ul_mcs; UL_alloc_pdu.ndi = phy_vars_eNB->proc[sched_subframe].frame_tx&1; UL_alloc_pdu.TPC = 0; if ((cooperation_flag==0) || (cooperation_flag==1)) UL_alloc_pdu.cshift = 0; else UL_alloc_pdu.cshift = 1; UL_alloc_pdu.dai = 0; UL_alloc_pdu.cqi_req = 1; memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&UL_alloc_pdu,sizeof(DCI0_5MHz_TDD_1_6_t)); */ break; default: break; } DCI_pdu->nCCE = 0; for (i=0; i<DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci; i++) { DCI_pdu->nCCE += (1<<(DCI_pdu->dci_alloc[i].L)); } } #ifdef EMOS void fill_dci_emos(DCI_PDU *DCI_pdu, uint8_t subframe, PHY_VARS_eNB *phy_vars_eNB) { int i; uint8_t cooperation_flag = phy_vars_eNB->cooperation_flag; uint8_t transmission_mode = phy_vars_eNB->transmission_mode[0]; //uint32_t rballoc = 0x00F0; //uint32_t rballoc2 = 0x000F; /* uint32_t rand = taus(); if ((subframe==8) || (subframe==9) || (subframe==0)) rand = (rand%5)+5; else rand = (rand%4)+5; */ DCI_pdu->Num_common_dci = 0; DCI_pdu->Num_ue_spec_dci=0; switch (subframe) { case 5: DCI_pdu->Num_ue_spec_dci = 1; if (transmission_mode<3) { //user 1 DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1_5MHz_TDD_t; DCI_pdu->dci_alloc[0].L = 2; DCI_pdu->dci_alloc[0].rnti = 0x1235; DCI_pdu->dci_alloc[0].format = format1; DCI_pdu->dci_alloc[0].ra_flag = 0; DLSCH_alloc_pdu.rballoc = openair_daq_vars.ue_dl_rb_alloc; DLSCH_alloc_pdu.TPC = 0; DLSCH_alloc_pdu.dai = 0; DLSCH_alloc_pdu.harq_pid = 1; DLSCH_alloc_pdu.mcs = openair_daq_vars.target_ue_dl_mcs; DLSCH_alloc_pdu.ndi = 1; DLSCH_alloc_pdu.rv = 0; memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&DLSCH_alloc_pdu,sizeof(DCI1_5MHz_TDD_t)); /* //user2 DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1_5MHz_TDD_t; DCI_pdu->dci_alloc[1].L = 2; DCI_pdu->dci_alloc[1].rnti = 0x1236; DCI_pdu->dci_alloc[1].format = format1; DCI_pdu->dci_alloc[1].ra_flag = 0; DLSCH_alloc_pdu.rballoc = rballoc2; DLSCH_alloc_pdu.TPC = 0; DLSCH_alloc_pdu.dai = 0; DLSCH_alloc_pdu.harq_pid = 1; DLSCH_alloc_pdu.mcs = openair_daq_vars.target_ue_dl_mcs; DLSCH_alloc_pdu.ndi = 1; DLSCH_alloc_pdu.rv = 0; memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&DLSCH_alloc_pdu,sizeof(DCI1_5MHz_TDD_t)); */ } else if (transmission_mode==5) { DCI_pdu->Num_ue_spec_dci = 2; // user 1 DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t; DCI_pdu->dci_alloc[0].L = 2; DCI_pdu->dci_alloc[0].rnti = 0x1235; DCI_pdu->dci_alloc[0].format = format1E_2A_M10PRB; DCI_pdu->dci_alloc[0].ra_flag = 0; DLSCH_alloc_pdu1E.tpmi = 5; //5=use feedback DLSCH_alloc_pdu1E.rv = 0; DLSCH_alloc_pdu1E.ndi = 1; DLSCH_alloc_pdu1E.mcs = openair_daq_vars.target_ue_dl_mcs; DLSCH_alloc_pdu1E.harq_pid = 1; DLSCH_alloc_pdu1E.dai = 0; DLSCH_alloc_pdu1E.TPC = 0; DLSCH_alloc_pdu1E.rballoc = openair_daq_vars.ue_dl_rb_alloc; DLSCH_alloc_pdu1E.rah = 0; DLSCH_alloc_pdu1E.dl_power_off = 0; //0=second user present memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&DLSCH_alloc_pdu1E,sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); //user 2 DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t; DCI_pdu->dci_alloc[1].L = 2; DCI_pdu->dci_alloc[1].rnti = 0x1236; DCI_pdu->dci_alloc[1].format = format1E_2A_M10PRB; DCI_pdu->dci_alloc[1].ra_flag = 0; memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&DLSCH_alloc_pdu1E,sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); // set the precoder of the second UE orthogonal to the first phy_vars_eNB->eNB_UE_stats[1].DL_pmi_single = (phy_vars_eNB->eNB_UE_stats[0].DL_pmi_single ^ 0x1555); } break; case 7: DCI_pdu->Num_common_dci = 1; DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; DCI_pdu->dci_alloc[0].L = 2; DCI_pdu->dci_alloc[0].rnti = 0xbeef; DCI_pdu->dci_alloc[0].format = format1A; DCI_pdu->dci_alloc[0].ra_flag = 1; RA_alloc_pdu.type = 1; RA_alloc_pdu.vrb_type = 0; RA_alloc_pdu.rballoc = computeRIV(25,12,3); RA_alloc_pdu.ndi = 1; RA_alloc_pdu.rv = 1; RA_alloc_pdu.mcs = 4; RA_alloc_pdu.harq_pid = 0; RA_alloc_pdu.TPC = 1; memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],&RA_alloc_pdu,sizeof(DCI1A_5MHz_TDD_1_6_t)); break; case 9: DCI_pdu->Num_ue_spec_dci = 1; //user 1 DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI0_5MHz_TDD_1_6_t ; DCI_pdu->dci_alloc[0].L = 2; DCI_pdu->dci_alloc[0].rnti = 0x1235; DCI_pdu->dci_alloc[0].format = format0; DCI_pdu->dci_alloc[0].ra_flag = 0; UL_alloc_pdu.type = 0; UL_alloc_pdu.hopping = 0; UL_alloc_pdu.rballoc = computeRIV(25,0,openair_daq_vars.ue_ul_nb_rb); UL_alloc_pdu.mcs = openair_daq_vars.target_ue_ul_mcs; UL_alloc_pdu.ndi = 1; UL_alloc_pdu.TPC = 0; UL_alloc_pdu.cshift = 0; UL_alloc_pdu.dai = 0; UL_alloc_pdu.cqi_req = 1; memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&UL_alloc_pdu,sizeof(DCI0_5MHz_TDD_1_6_t)); /* //user 2 DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI0_5MHz_TDD_1_6_t ; DCI_pdu->dci_alloc[1].L = 2; DCI_pdu->dci_alloc[1].rnti = 0x1236; DCI_pdu->dci_alloc[1].format = format0; DCI_pdu->dci_alloc[1].ra_flag = 0; UL_alloc_pdu.type = 0; UL_alloc_pdu.hopping = 0; if (cooperation_flag==0) UL_alloc_pdu.rballoc = computeRIV(25,2+openair_daq_vars.ue_ul_nb_rb,openair_daq_vars.ue_ul_nb_rb); else UL_alloc_pdu.rballoc = computeRIV(25,0,openair_daq_vars.ue_ul_nb_rb); UL_alloc_pdu.mcs = openair_daq_vars.target_ue_ul_mcs; UL_alloc_pdu.ndi = 1; UL_alloc_pdu.TPC = 0; if ((cooperation_flag==0) || (cooperation_flag==1)) UL_alloc_pdu.cshift = 0; else UL_alloc_pdu.cshift = 1; UL_alloc_pdu.dai = 0; UL_alloc_pdu.cqi_req = 1; memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&UL_alloc_pdu,sizeof(DCI0_5MHz_TDD_1_6_t)); */ break; default: break; } DCI_pdu->nCCE = 0; for (i=0; i<DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci; i++) { DCI_pdu->nCCE += (1<<(DCI_pdu->dci_alloc[i].L)); } } #endif //EMOS #endif //OPENAIR2 #define AMP_OVER_SQRT2 ((AMP*ONE_OVER_SQRT2_Q15)>>15) #define AMP_OVER_2 (AMP>>1) int QPSK[4]= {AMP_OVER_SQRT2|(AMP_OVER_SQRT2<<16),AMP_OVER_SQRT2|((65536-AMP_OVER_SQRT2)<<16),((65536-AMP_OVER_SQRT2)<<16)|AMP_OVER_SQRT2,((65536-AMP_OVER_SQRT2)<<16)|(65536-AMP_OVER_SQRT2)}; int QPSK2[4]= {AMP_OVER_2|(AMP_OVER_2<<16),AMP_OVER_2|((65536-AMP_OVER_2)<<16),((65536-AMP_OVER_2)<<16)|AMP_OVER_2,((65536-AMP_OVER_2)<<16)|(65536-AMP_OVER_2)}; #if defined(ENABLE_ITTI) # if ENABLE_RAL extern PHY_MEASUREMENTS PHY_measurements; void phy_eNB_lte_measurement_thresholds_test_and_report(instance_t instanceP, ral_threshold_phy_t* threshold_phy_pP, uint16_t valP) { MessageDef *message_p = NULL; if ( ( ((threshold_phy_pP->threshold.threshold_val < valP) && (threshold_phy_pP->threshold.threshold_xdir == RAL_ABOVE_THRESHOLD)) || ((threshold_phy_pP->threshold.threshold_val > valP) && (threshold_phy_pP->threshold.threshold_xdir == RAL_BELOW_THRESHOLD)) ) || (threshold_phy_pP->threshold.threshold_xdir == RAL_NO_THRESHOLD) ) { message_p = itti_alloc_new_message(TASK_PHY_ENB , PHY_MEAS_REPORT_IND); memset(&PHY_MEAS_REPORT_IND(message_p), 0, sizeof(PHY_MEAS_REPORT_IND(message_p))); memcpy(&PHY_MEAS_REPORT_IND (message_p).threshold, &threshold_phy_pP->threshold, sizeof(PHY_MEAS_REPORT_IND (message_p).threshold)); memcpy(&PHY_MEAS_REPORT_IND (message_p).link_param, &threshold_phy_pP->link_param, sizeof(PHY_MEAS_REPORT_IND (message_p).link_param)); \ switch (threshold_phy_pP->link_param.choice) { case RAL_LINK_PARAM_CHOICE_LINK_PARAM_VAL: PHY_MEAS_REPORT_IND (message_p).link_param._union.link_param_val = valP; break; case RAL_LINK_PARAM_CHOICE_QOS_PARAM_VAL: //PHY_MEAS_REPORT_IND (message_p).link_param._union.qos_param_val. AssertFatal (1 == 0, "TO DO RAL_LINK_PARAM_CHOICE_QOS_PARAM_VAL\n"); break; } itti_send_msg_to_task(TASK_RRC_ENB, instanceP, message_p); } } void phy_eNB_lte_check_measurement_thresholds(instance_t instanceP, ral_threshold_phy_t* threshold_phy_pP) { unsigned int mod_id; mod_id = instanceP; switch (threshold_phy_pP->link_param.link_param_type.choice) { case RAL_LINK_PARAM_TYPE_CHOICE_GEN: switch (threshold_phy_pP->link_param.link_param_type._union.link_param_gen) { case RAL_LINK_PARAM_GEN_DATA_RATE: phy_eNB_lte_measurement_thresholds_test_and_report(instanceP, threshold_phy_pP, 0); break; case RAL_LINK_PARAM_GEN_SIGNAL_STRENGTH: phy_eNB_lte_measurement_thresholds_test_and_report(instanceP, threshold_phy_pP, 0); break; case RAL_LINK_PARAM_GEN_SINR: phy_eNB_lte_measurement_thresholds_test_and_report(instanceP, threshold_phy_pP, 0); break; case RAL_LINK_PARAM_GEN_THROUGHPUT: break; case RAL_LINK_PARAM_GEN_PACKET_ERROR_RATE: break; default: ; } break; case RAL_LINK_PARAM_TYPE_CHOICE_LTE: switch (threshold_phy_pP->link_param.link_param_type._union.link_param_gen) { case RAL_LINK_PARAM_LTE_UE_RSRP: break; case RAL_LINK_PARAM_LTE_UE_RSRQ: break; case RAL_LINK_PARAM_LTE_UE_CQI: break; case RAL_LINK_PARAM_LTE_AVAILABLE_BW: break; case RAL_LINK_PARAM_LTE_PACKET_DELAY: break; case RAL_LINK_PARAM_LTE_PACKET_LOSS_RATE: break; case RAL_LINK_PARAM_LTE_L2_BUFFER_STATUS: break; case RAL_LINK_PARAM_LTE_MOBILE_NODE_CAPABILITIES: break; case RAL_LINK_PARAM_LTE_EMBMS_CAPABILITY: break; case RAL_LINK_PARAM_LTE_JUMBO_FEASIBILITY: break; case RAL_LINK_PARAM_LTE_JUMBO_SETUP_STATUS: break; case RAL_LINK_PARAM_LTE_NUM_ACTIVE_EMBMS_RECEIVERS_PER_FLOW: break; default: ; } break; default: ; } } # endif #endif void phy_procedures_eNB_TX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_eNB,uint8_t abstraction_flag, relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn) { UNUSED(phy_vars_rn); uint8_t *pbch_pdu=&phy_vars_eNB->pbch_pdu[0]; uint16_t input_buffer_length, re_allocated=0; uint32_t i,aa; uint8_t harq_pid; DCI_PDU *DCI_pdu; uint8_t *DLSCH_pdu=NULL; #ifndef OPENAIR2 DCI_PDU DCI_pdu_tmp; uint8_t DLSCH_pdu_tmp[768*8]; #endif int8_t UE_id; uint8_t num_pdcch_symbols=0; uint8_t ul_subframe; uint32_t ul_frame; #ifdef Rel10 MCH_PDU *mch_pduP; MCH_PDU mch_pdu; // uint8_t sync_area=255; #endif #if defined(SMBV) && !defined(EXMIMO) // counts number of allocations in subframe // there is at least one allocation for PDCCH uint8_t smbv_alloc_cnt = 1; #endif int frame = phy_vars_eNB->proc[sched_subframe].frame_tx; int subframe = phy_vars_eNB->proc[sched_subframe].subframe_tx; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX,1); start_meas(&phy_vars_eNB->phy_proc_tx); #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[%s %"PRIu8"] Frame %d subframe %d : Doing phy_procedures_eNB_TX\n", (r_type == multicast_relay) ? "RN/eNB" : "eNB", phy_vars_eNB->Mod_id, frame, subframe); #endif for (i=0; i<NUMBER_OF_UE_MAX; i++) { // If we've dropped the UE, go back to PRACH mode for this UE //#if !defined(EXMIMO_IOT) if (phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors == ULSCH_max_consecutive_errors) { LOG_W(PHY,"[eNB %d, CC %d] frame %d, subframe %d, UE %d: ULSCH consecutive error count reached %u, removing UE\n", phy_vars_eNB->Mod_id,phy_vars_eNB->CC_id,frame,subframe, i, phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors); phy_vars_eNB->eNB_UE_stats[i].mode = PRACH; remove_ue(phy_vars_eNB->eNB_UE_stats[i].crnti,phy_vars_eNB,abstraction_flag); phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors=0; } //#endif } #ifdef OPENAIR2 // Get scheduling info for next subframe if (phy_vars_eNB->CC_id == 0) mac_xface->eNB_dlsch_ulsch_scheduler(phy_vars_eNB->Mod_id,0,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe);//,1); #endif if (abstraction_flag==0) { // clear the transmit data array for the current subframe for (aa=0; aa<phy_vars_eNB->lte_frame_parms.nb_antennas_tx_eNB; aa++) { memset(&phy_vars_eNB->lte_eNB_common_vars.txdataF[0][aa][subframe*phy_vars_eNB->lte_frame_parms.ofdm_symbol_size*(phy_vars_eNB->lte_frame_parms.symbols_per_tti)], 0,phy_vars_eNB->lte_frame_parms.ofdm_symbol_size*(phy_vars_eNB->lte_frame_parms.symbols_per_tti)*sizeof(mod_sym_t)); } } if (is_pmch_subframe(phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,&phy_vars_eNB->lte_frame_parms)) { if (abstraction_flag==0) { // This is DL-Cell spec pilots in Control region generate_pilots_slot(phy_vars_eNB, phy_vars_eNB->lte_eNB_common_vars.txdataF[0], AMP, subframe<<1,1); } #ifdef Rel10 // if mcch is active, send regardless of the node type: eNB or RN // when mcch is active, MAC sched does not allow MCCH and MTCH multiplexing mch_pduP = mac_xface->get_mch_sdu(phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, phy_vars_eNB->proc[sched_subframe].frame_tx, subframe); switch (r_type) { case no_relay: if ((mch_pduP->Pdu_size > 0) && (mch_pduP->sync_area == 0)) // TEST: only transmit mcch for sync area 0 LOG_I(PHY,"[eNB%"PRIu8"] Frame %d subframe %d : Got MCH pdu for MBSFN (MCS %"PRIu8", TBS %d) \n", phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,mch_pduP->mcs, phy_vars_eNB->dlsch_eNB_MCH->harq_processes[0]->TBS>>3); else { LOG_D(PHY,"[DeNB %"PRIu8"] Frame %d subframe %d : Do not transmit MCH pdu for MBSFN sync area %"PRIu8" (%s)\n", phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,mch_pduP->sync_area, (mch_pduP->Pdu_size == 0)? "Empty MCH PDU":"Let RN transmit for the moment"); mch_pduP = NULL; } break; case multicast_relay: if ((mch_pduP->Pdu_size > 0) && ((mch_pduP->mcch_active == 1) || mch_pduP->msi_active==1)) { LOG_I(PHY,"[RN %"PRIu8"] Frame %d subframe %d: Got the MCH PDU for MBSFN sync area %"PRIu8" (MCS %"PRIu8", TBS %"PRIu16")\n", phy_vars_rn->Mod_id,phy_vars_rn->frame, subframe, mch_pduP->sync_area,mch_pduP->mcs,mch_pduP->Pdu_size); } else if (phy_vars_rn->mch_avtive[subframe%5] == 1) { // SF2 -> SF7, SF3 -> SF8 mch_pduP= &mch_pdu; memcpy(&mch_pduP->payload, // could be a simple copy phy_vars_rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->b, phy_vars_rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->TBS>>3); mch_pduP->Pdu_size = (uint16_t) (phy_vars_rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->TBS>>3); mch_pduP->mcs = phy_vars_rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->mcs; LOG_I(PHY,"[RN %"PRIu8"] Frame %d subframe %d: Forward the MCH PDU for MBSFN received on SF %d sync area %"PRIu8" (MCS %"PRIu8", TBS %"PRIu16")\n", phy_vars_rn->Mod_id,phy_vars_rn->frame, subframe,subframe%5, phy_vars_rn->sync_area[subframe%5],mch_pduP->mcs,mch_pduP->Pdu_size); } else { /* LOG_I(PHY,"[RN %d] Frame %d subframe %d: do not forward MCH pdu for MBSFN sync area %d (MCS %d, TBS %d)\n", phy_vars_rn->Mod_id,phy_vars_rn->frame, next_slot>>1, mch_pduP->sync_area,mch_pduP->mcs,mch_pduP->Pdu_size);*/ mch_pduP=NULL; } phy_vars_rn->mch_avtive[subframe]=0; break; default: LOG_W(PHY,"[eNB %"PRIu8"] Frame %d subframe %d: unknown relaying type %d \n", phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,r_type); mch_pduP=NULL; break; }// switch if (mch_pduP) { fill_eNB_dlsch_MCH(phy_vars_eNB,mch_pduP->mcs,1,0, abstraction_flag); // Generate PMCH generate_mch(phy_vars_eNB,sched_subframe,(uint8_t*)mch_pduP->payload,abstraction_flag); #ifdef DEBUG_PHY for (i=0; i<mch_pduP->Pdu_size; i++) msg("%2"PRIx8".",(uint8_t)mch_pduP->payload[i]); msg("\n"); #endif } else { LOG_D(PHY,"[eNB/RN] Frame %d subframe %d: MCH not generated \n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe); } #endif } else { // this is not a pmch subframe if (abstraction_flag==0) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,1); generate_pilots_slot(phy_vars_eNB, phy_vars_eNB->lte_eNB_common_vars.txdataF[0], AMP, subframe<<1,0); if (subframe_select(&phy_vars_eNB->lte_frame_parms,subframe) == SF_DL) generate_pilots_slot(phy_vars_eNB, phy_vars_eNB->lte_eNB_common_vars.txdataF[0], AMP, (subframe<<1)+1,0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,0); // First half of PSS/SSS (FDD) if (subframe == 0) { if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) { generate_pss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0], AMP, &phy_vars_eNB->lte_frame_parms, (phy_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 6 : 5, 0); generate_sss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0], AMP, &phy_vars_eNB->lte_frame_parms, (phy_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 5 : 4, 0); } } } } if (subframe == 0) { // generate PBCH (Physical Broadcast CHannel) info if ((phy_vars_eNB->proc[sched_subframe].frame_tx&3) == 0) { pbch_pdu[2] = 0; // FIXME setting pbch_pdu[2] to zero makes the switch statement easier: remove all the or-operators switch (phy_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (0<<5); break; case 15: pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (1<<5); break; case 25: pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5); break; case 50: pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (3<<5); break; case 75: pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (4<<5); break; case 100: pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (5<<5); break; default: // FIXME if we get here, this should be flagged as an error, right? pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5); break; } pbch_pdu[2] = (pbch_pdu[2]&0xef) | ((phy_vars_eNB->lte_frame_parms.phich_config_common.phich_duration << 4)&0x10); switch (phy_vars_eNB->lte_frame_parms.phich_config_common.phich_resource) { case oneSixth: pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (0<<2); break; case half: pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (1<<2); break; case one: pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (2<<2); break; case two: pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (3<<2); break; default: // unreachable break; } pbch_pdu[2] = (pbch_pdu[2]&0xfc) | ((phy_vars_eNB->proc[sched_subframe].frame_tx>>8)&0x3); pbch_pdu[1] = phy_vars_eNB->proc[sched_subframe].frame_tx&0xfc; pbch_pdu[0] = 0; } /// First half of SSS (TDD) if (abstraction_flag==0) { if (phy_vars_eNB->lte_frame_parms.frame_type == TDD) { generate_sss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0], AMP, &phy_vars_eNB->lte_frame_parms, (phy_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 6 : 5, 1); } } #ifdef DEBUG_PHY_PROC uint16_t frame_tx = (((int) (pbch_pdu[2]&0x3))<<8) + ((int) (pbch_pdu[1]&0xfc)) + phy_vars_eNB->proc[sched_subframe].frame_tx%4; LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Generating PBCH, mode1_flag=%"PRIu8", frame_tx=%"PRIu16", pdu=%02"PRIx8"%02"PRIx8"%02"PRIx8"\n", phy_vars_eNB->Mod_id, phy_vars_eNB->proc[sched_subframe].frame_tx, subframe, phy_vars_eNB->lte_frame_parms.mode1_flag, frame_tx, pbch_pdu[2], pbch_pdu[1], pbch_pdu[0]); #endif if (abstraction_flag==0) { generate_pbch(&phy_vars_eNB->lte_eNB_pbch, phy_vars_eNB->lte_eNB_common_vars.txdataF[0], AMP, &phy_vars_eNB->lte_frame_parms, pbch_pdu, phy_vars_eNB->proc[sched_subframe].frame_tx&3); } #ifdef PHY_ABSTRACTION else { generate_pbch_emul(phy_vars_eNB,pbch_pdu); } #endif } if (subframe == 1) { if (abstraction_flag==0) { if (phy_vars_eNB->lte_frame_parms.frame_type == TDD) { // printf("Generating PSS (frame %d, subframe %d)\n",phy_vars_eNB->proc[sched_subframe].frame_tx,next_slot>>1); generate_pss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0], AMP, &phy_vars_eNB->lte_frame_parms, 2, 2); } } } // Second half of PSS/SSS (FDD) if (subframe == 5) { if (abstraction_flag==0) { if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) { generate_pss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0], AMP, &phy_vars_eNB->lte_frame_parms, (phy_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 6 : 5, 10); generate_sss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0], AMP, &phy_vars_eNB->lte_frame_parms, (phy_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 5 : 4, 10); } } } // Second-half of SSS (TDD) if (subframe == 5) { if (abstraction_flag==0) { if (phy_vars_eNB->lte_frame_parms.frame_type == TDD) { generate_sss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0], AMP, &phy_vars_eNB->lte_frame_parms, (phy_vars_eNB->lte_frame_parms.Ncp==NORMAL) ? 6 : 5, 11); } } } // Second half of PSS (TDD) if (subframe == 6) { if (abstraction_flag==0) { if (phy_vars_eNB->lte_frame_parms.frame_type == TDD) { // printf("Generating PSS (frame %d, subframe %d)\n",phy_vars_eNB->proc[sched_subframe].frame_tx,next_slot>>1); generate_pss(phy_vars_eNB->lte_eNB_common_vars.txdataF[0], AMP, &phy_vars_eNB->lte_frame_parms, 2, 12); } } } // sect_id=0; #if defined(SMBV) && !defined(EXMIMO) // PBCH takes one allocation if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) { if (subframe==0) smbv_alloc_cnt++; } #endif #ifdef OPENAIR2 // Parse DCI received from MAC VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,1); DCI_pdu = mac_xface->get_dci_sdu(phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, phy_vars_eNB->proc[sched_subframe].frame_tx, subframe); #else DCI_pdu = &DCI_pdu_tmp; #ifdef EMOS /* if (((phy_vars_eNB->proc[sched_subframe].frame_tx%1024)%3 == 0) && (next_slot == 0)) { //openair_daq_vars.target_ue_dl_mcs = (openair_daq_vars.target_ue_dl_mcs+1)%28; openair_daq_vars.target_ue_dl_mcs = taus()%28; LOG_D(PHY,"[MYEMOS] frame %d, increasing MCS to %d\n",phy_vars_eNB->proc[sched_subframe].frame_tx,openair_daq_vars.target_ue_dl_mcs); } */ /* if (phy_vars_eNB->proc[sched_subframe].frame_tx > 28000) { LOG_E(PHY,"More that 28000 frames reached! Exiting!\n"); } */ #endif #ifdef EMOS_CHANNEL fill_dci_emos(DCI_pdu,sched_subframe,phy_vars_eNB); #else fill_dci(DCI_pdu,sched_subframe,phy_vars_eNB); #endif #endif // clear existing ulsch dci allocations before applying info from MAC (this is table ul_subframe = pdcch_alloc2ul_subframe(&phy_vars_eNB->lte_frame_parms,subframe); ul_frame = pdcch_alloc2ul_frame(&phy_vars_eNB->lte_frame_parms,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe); if ((subframe_select(&phy_vars_eNB->lte_frame_parms,ul_subframe)==SF_UL) || (phy_vars_eNB->lte_frame_parms.frame_type == FDD)) { harq_pid = subframe2harq_pid(&phy_vars_eNB->lte_frame_parms,ul_frame,ul_subframe); for (i=0; i<NUMBER_OF_UE_MAX; i++) if (phy_vars_eNB->ulsch_eNB[i]) { phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->dci_alloc=0; phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->rar_alloc=0; } } #ifdef EMOS //emos_dump_eNB.dci_cnt[next_slot>>1] = DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci; //nb_dci_common+nb_dci_ue_spec; #endif // clear previous allocation information for all UEs for (i=0; i<NUMBER_OF_UE_MAX; i++) { phy_vars_eNB->dlsch_eNB[i][0]->subframe_tx[subframe] = 0; } init_nCCE_table(); num_pdcch_symbols = get_num_pdcch_symbols(DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci, DCI_pdu->dci_alloc, &phy_vars_eNB->lte_frame_parms, subframe); DCI_pdu->nCCE = get_nCCE(num_pdcch_symbols, &phy_vars_eNB->lte_frame_parms, get_mi(&phy_vars_eNB->lte_frame_parms,subframe)); LOG_D(PHY,"num_pdcch_symbols %"PRIu8", nCCE %u (dci commond %"PRIu8", dci uespec %"PRIu8"\n",num_pdcch_symbols,DCI_pdu->nCCE, DCI_pdu->Num_common_dci,DCI_pdu->Num_ue_spec_dci); #if defined(SMBV) && !defined(EXMIMO) // Sets up PDCCH and DCI table if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4) && ((DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci)>0)) { msg("[SMBV] Frame %3d, SF %d PDCCH, number of DCIs %d\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci); dump_dci(&phy_vars_eNB->lte_frame_parms,&DCI_pdu->dci_alloc[0]); smbv_configure_pdcch(smbv_fname,(smbv_frame_cnt*10) + (subframe),num_pdcch_symbols,DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci); } #endif for (i=0; i<DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci ; i++) { #ifdef DEBUG_PHY_PROC if (DCI_pdu->dci_alloc[i].rnti != SI_RNTI) { LOG_D(PHY,"[eNB] Subframe %d : Doing DCI index %"PRIu32"/%d\n",subframe,i,DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci); dump_dci(&phy_vars_eNB->lte_frame_parms,&DCI_pdu->dci_alloc[i]); } #endif if (DCI_pdu->dci_alloc[i].rnti == SI_RNTI) { #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %"PRIu8"] SI generate_eNB_dlsch_params_from_dci\n", phy_vars_eNB->Mod_id); #endif generate_eNB_dlsch_params_from_dci(frame, subframe, &DCI_pdu->dci_alloc[i].dci_pdu[0], DCI_pdu->dci_alloc[i].rnti, DCI_pdu->dci_alloc[i].format, &phy_vars_eNB->dlsch_eNB_SI, &phy_vars_eNB->lte_frame_parms, phy_vars_eNB->pdsch_config_dedicated, SI_RNTI, 0, P_RNTI, phy_vars_eNB->eNB_UE_stats[0].DL_pmi_single); int result = get_nCCE_offset(1<<DCI_pdu->dci_alloc[i].L, DCI_pdu->nCCE, 1, SI_RNTI, subframe); phy_vars_eNB->dlsch_eNB_SI->nCCE[subframe] = result; if (result == -1) { // FIXME what happens to phy_vars_eNB->dlsch_eNB_SI->nCCE[subframe]? LOG_E(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : No available CCE resources for common DCI (SI)!!!\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe); } else { LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (SI) => %"PRIu8"/%u\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe, phy_vars_eNB->dlsch_eNB_SI->nCCE[subframe],DCI_pdu->nCCE); #if defined(SMBV) && !defined(EXMIMO) // configure SI DCI if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) { msg("[SMBV] Frame %3d, SI in SF %d DCI %"PRIu32"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,i); smbv_configure_common_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), "SI", &DCI_pdu->dci_alloc[i], i); } #endif } DCI_pdu->dci_alloc[i].nCCE = phy_vars_eNB->dlsch_eNB_SI->nCCE[subframe]; } else if (DCI_pdu->dci_alloc[i].ra_flag == 1) { #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %"PRIu8"] RA generate_eNB_dlsch_params_from_dci\n", phy_vars_eNB->Mod_id); #endif generate_eNB_dlsch_params_from_dci(frame, subframe, &DCI_pdu->dci_alloc[i].dci_pdu[0], DCI_pdu->dci_alloc[i].rnti, DCI_pdu->dci_alloc[i].format, &phy_vars_eNB->dlsch_eNB_ra, &phy_vars_eNB->lte_frame_parms, phy_vars_eNB->pdsch_config_dedicated, SI_RNTI, DCI_pdu->dci_alloc[i].rnti, P_RNTI, phy_vars_eNB->eNB_UE_stats[0].DL_pmi_single); // mac_xface->macphy_exit("Transmitted RAR, exiting\n"); int result = get_nCCE_offset(1<<DCI_pdu->dci_alloc[i].L, DCI_pdu->nCCE, 1, DCI_pdu->dci_alloc[i].rnti, subframe); phy_vars_eNB->dlsch_eNB_ra->nCCE[subframe] = result; if (result == -1) { // FIXME what happens to phy_vars_eNB->dlsch_eNB_ra->nCCE[subframe]? LOG_E(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : No available CCE resources for common DCI (RA) !!!\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe); } else { LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (RA) => %"PRIu8"/%u\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe, phy_vars_eNB->dlsch_eNB_ra->nCCE[subframe],DCI_pdu->nCCE); #if defined(SMBV) && !defined(EXMIMO) // configure RA DCI if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) { msg("[SMBV] Frame %3d, RA in SF %d DCI %"PRIu32"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,i); smbv_configure_common_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), "RA", &DCI_pdu->dci_alloc[i], i); } #endif } DCI_pdu->dci_alloc[i].nCCE = phy_vars_eNB->dlsch_eNB_ra->nCCE[subframe]; } else if (DCI_pdu->dci_alloc[i].format != format0) { // this is a normal DLSCH allocation #ifdef OPENAIR2 #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB] Searching for RNTI %"PRIx16"\n",DCI_pdu->dci_alloc[i].rnti); #endif UE_id = find_ue((int16_t)DCI_pdu->dci_alloc[i].rnti,phy_vars_eNB); #else UE_id = i; #endif if (UE_id>=0) { // dump_dci(&phy_vars_eNB->lte_frame_parms,&DCI_pdu->dci_alloc[i]); #if defined(SMBV) && !defined(EXMIMO) // Configure this user if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) { msg("[SMBV] Frame %3d, SF %d (SMBV SF %d) Configuring user %d with RNTI %"PRIu16" in TM%"PRIu8"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,(smbv_frame_cnt*10) + (subframe),UE_id+1, DCI_pdu->dci_alloc[i].rnti,phy_vars_eNB->transmission_mode[(uint8_t)UE_id]); smbv_configure_user(smbv_fname,UE_id+1,phy_vars_eNB->transmission_mode[(uint8_t)UE_id],DCI_pdu->dci_alloc[i].rnti); } #endif generate_eNB_dlsch_params_from_dci(frame, subframe, &DCI_pdu->dci_alloc[i].dci_pdu[0], DCI_pdu->dci_alloc[i].rnti, DCI_pdu->dci_alloc[i].format, phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id], &phy_vars_eNB->lte_frame_parms, phy_vars_eNB->pdsch_config_dedicated, SI_RNTI, 0, P_RNTI, phy_vars_eNB->eNB_UE_stats[(uint8_t)UE_id].DL_pmi_single); LOG_D(PHY,"[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d subframe %d: Generated dlsch params\n", phy_vars_eNB->Mod_id,DCI_pdu->dci_alloc[i].rnti,phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->current_harq_pid,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe); int result = get_nCCE_offset(1<<DCI_pdu->dci_alloc[i].L, DCI_pdu->nCCE, 0, DCI_pdu->dci_alloc[i].rnti, subframe); phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->nCCE[subframe] = result; if (result == -1) { // FIXME what happens to phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->nCCE[subframe]? LOG_E(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : No available CCE resources for UE spec DCI (PDSCH %"PRIx16") !!!\n", phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,DCI_pdu->dci_alloc[i].rnti); } else { LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for ue DCI (PDSCH %"PRIx16") => %"PRIu8"/%u\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe, DCI_pdu->dci_alloc[i].rnti,phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->nCCE[subframe],DCI_pdu->nCCE); #if defined(SMBV) && !defined(EXMIMO) DCI_pdu->dci_alloc[i].nCCE = phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->nCCE[subframe]; // configure UE-spec DCI if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) { msg("[SMBV] Frame %3d, PDSCH in SF %d DCI %"PRIu32"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,i); smbv_configure_ue_spec_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), UE_id+1, &DCI_pdu->dci_alloc[i], i); } #endif } DCI_pdu->dci_alloc[i].nCCE = phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->nCCE[subframe]; #ifdef DEBUG_PHY_PROC //if (phy_vars_eNB->proc[sched_subframe].frame_tx%100 == 0) LOG_D(PHY,"[eNB %"PRIu8"][DCI][PDSCH %"PRIx16"] Frame %d subframe %d UE_id %"PRId8" Generated DCI format %d, aggregation %d\n", phy_vars_eNB->Mod_id, DCI_pdu->dci_alloc[i].rnti, phy_vars_eNB->proc[sched_subframe].frame_tx, subframe,UE_id, DCI_pdu->dci_alloc[i].format, 1<<DCI_pdu->dci_alloc[i].L); #endif } else { LOG_D(PHY,"[eNB %"PRIu8"][PDSCH] Frame %d : No UE_id with corresponding rnti %"PRIx16", dropping DLSCH\n", phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,DCI_pdu->dci_alloc[i].rnti); } } } // Apply physicalConfigDedicated if needed phy_config_dedicated_eNB_step2(phy_vars_eNB); for (i=0; i<DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci ; i++) { if (DCI_pdu->dci_alloc[i].format == format0) { // this is a ULSCH allocation harq_pid = subframe2harq_pid(&phy_vars_eNB->lte_frame_parms, pdcch_alloc2ul_frame(&phy_vars_eNB->lte_frame_parms,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe), pdcch_alloc2ul_subframe(&phy_vars_eNB->lte_frame_parms,subframe)); if (harq_pid==255) { LOG_E(PHY,"[eNB %"PRIu8"] Frame %d: Bad harq_pid for ULSCH allocation\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx); //mac_exit_wrapper("Invalid harq_pid (255) detected"); return; // not reached } #ifdef OPENAIR2 UE_id = find_ue((int16_t)DCI_pdu->dci_alloc[i].rnti,phy_vars_eNB); #else UE_id = i; #endif if (UE_id<0) { LOG_E(PHY,"[eNB %"PRIu8"] Frame %d: Unknown UE_id for rnti %"PRIx16"\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,DCI_pdu->dci_alloc[i].rnti); mac_exit_wrapper("Invalid UE id (< 0) detected"); return; // not reached } #ifdef DEBUG_PHY_PROC //if (phy_vars_eNB->proc[sched_subframe].frame_tx%100 == 0) LOG_D(PHY, "[eNB %"PRIu8"][PUSCH %"PRIu8"] Frame %d subframe %d UL Frame %"PRIu32", UL Subframe %"PRIu8", Generated ULSCH (format0) DCI (rnti %"PRIx16", dci %"PRIx8") (DCI pos %"PRIu32"/%d), aggregation %d\n", phy_vars_eNB->Mod_id, subframe2harq_pid(&phy_vars_eNB->lte_frame_parms, pdcch_alloc2ul_frame(&phy_vars_eNB->lte_frame_parms,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe), pdcch_alloc2ul_subframe(&phy_vars_eNB->lte_frame_parms,subframe)), phy_vars_eNB->proc[sched_subframe].frame_tx, subframe, pdcch_alloc2ul_frame(&phy_vars_eNB->lte_frame_parms,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe), pdcch_alloc2ul_subframe(&phy_vars_eNB->lte_frame_parms,subframe), DCI_pdu->dci_alloc[i].rnti, DCI_pdu->dci_alloc[i].dci_pdu[0], i, DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci, 1<<DCI_pdu->dci_alloc[i].L); #endif //dump_dci(&phy_vars_eNB->lte_frame_parms,&DCI_pdu->dci_alloc[i]); //LOG_D(PHY,"[eNB] cba generate_eNB_ulsch_params_from_dci for ue %d for dci rnti %x\n", UE_id, DCI_pdu->dci_alloc[i].rnti); generate_eNB_ulsch_params_from_dci(&DCI_pdu->dci_alloc[i].dci_pdu[0], DCI_pdu->dci_alloc[i].rnti, sched_subframe, format0, UE_id, phy_vars_eNB, SI_RNTI, 0, P_RNTI, CBA_RNTI, 0); // do_srs if ((DCI_pdu->dci_alloc[i].nCCE=get_nCCE_offset(1<<DCI_pdu->dci_alloc[i].L, DCI_pdu->nCCE, 0, DCI_pdu->dci_alloc[i].rnti, subframe)) == -1) { LOG_E(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : No available CCE resources (%u) for UE spec DCI (PUSCH %"PRIx16") !!!\n", phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,DCI_pdu->nCCE,DCI_pdu->dci_alloc[i].rnti); } else { LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resources for UE spec DCI (PUSCH %"PRIx16") => %d/%u\n", phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,DCI_pdu->dci_alloc[i].rnti, DCI_pdu->dci_alloc[i].nCCE,DCI_pdu->nCCE); #if defined(SMBV) && !defined(EXMIMO) // configure UE-spec DCI for UL Grant if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) { msg("[SMBV] Frame %3d, SF %d UL DCI %"PRIu32"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,i); smbv_configure_ue_spec_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), UE_id+1, &DCI_pdu->dci_alloc[i], i); } #endif } #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %"PRIu8"][PUSCH %"PRIu8"] frame %d subframe %d Setting subframe_scheduling_flag for UE %"PRIu32" harq_pid %"PRIu8" (ul subframe %"PRIu8")\n", phy_vars_eNB->Mod_id,harq_pid, phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,i,harq_pid, pdcch_alloc2ul_subframe(&phy_vars_eNB->lte_frame_parms,subframe)); #endif if ((DCI_pdu->dci_alloc[i].rnti >= CBA_RNTI) && (DCI_pdu->dci_alloc[i].rnti < P_RNTI)) phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_cba_scheduling_flag = 1; else phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1; } } // if we have DCI to generate do it now if ((DCI_pdu->Num_common_dci + DCI_pdu->Num_ue_spec_dci)>0) { } else { // for emulation!! phy_vars_eNB->num_ue_spec_dci[(subframe)&1]=0; phy_vars_eNB->num_common_dci[(subframe)&1]=0; } if (abstraction_flag == 0) { #ifdef DEBUG_PHY_PROC if (DCI_pdu->Num_ue_spec_dci+DCI_pdu->Num_common_dci > 0) LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top (pdcch) (common %"PRIu8",ue_spec %"PRIu8")\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, subframe, DCI_pdu->Num_common_dci,DCI_pdu->Num_ue_spec_dci); #endif // for (sect_id=0;sect_id<number_of_cards;sect_id++) num_pdcch_symbols = generate_dci_top(DCI_pdu->Num_ue_spec_dci, DCI_pdu->Num_common_dci, DCI_pdu->dci_alloc, 0, AMP, &phy_vars_eNB->lte_frame_parms, phy_vars_eNB->lte_eNB_common_vars.txdataF[0], subframe); #ifdef DEBUG_PHY_PROC // LOG_I(PHY,"[eNB %d] Frame %d, subframe %d: num_pdcch_symbols %d)\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, next_slot>>1,num_pdcch_symbols); #endif } #ifdef PHY_ABSTRACTION // FIXME this ifdef seems suspicious else { LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top_emul\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, subframe); num_pdcch_symbols = generate_dci_top_emul(phy_vars_eNB,DCI_pdu->Num_ue_spec_dci,DCI_pdu->Num_common_dci,DCI_pdu->dci_alloc,subframe); } #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0); #ifdef DEBUG_PHY_PROC //LOG_D(PHY,"[eNB %d] Frame %d, slot %d: num_pdcch_symbols=%d\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, next_slot,num_pdcch_symbols); #endif // Check for SI activity if (phy_vars_eNB->dlsch_eNB_SI->active == 1) { input_buffer_length = phy_vars_eNB->dlsch_eNB_SI->harq_processes[0]->TBS/8; #ifdef OPENAIR2 DLSCH_pdu = mac_xface->get_dlsch_sdu(phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, phy_vars_eNB->proc[sched_subframe].frame_tx, SI_RNTI, 0); #else DLSCH_pdu = DLSCH_pdu_tmp; for (i=0; i<input_buffer_length; i++) DLSCH_pdu[i] = (unsigned char)(taus()&0xff); #endif #if defined(SMBV) && !defined(EXMIMO) // Configures the data source of allocation (allocation is configured by DCI) if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) { msg("[SMBV] Frame %3d, Configuring SI payload in SF %d alloc %"PRIu8"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,(smbv_frame_cnt*10) + (subframe),smbv_alloc_cnt); smbv_configure_datalist_for_alloc(smbv_fname, smbv_alloc_cnt++, (smbv_frame_cnt*10) + (subframe), DLSCH_pdu, input_buffer_length); } #endif #ifdef DEBUG_PHY_PROC #ifdef DEBUG_DLSCH //FIXME: The code below is commented as next_slot is not defined which results in failed compilation /* LOG_D(PHY,"[eNB %"PRIu8"][SI] Frame %d, slot %d: Calling generate_dlsch (SI) with input size = %"PRIu16", num_pdcch_symbols %"PRIu8"\n", phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, next_slot, input_buffer_length,num_pdcch_symbols); // FIXME this code is broken (next_slot?) for (i=0; i<input_buffer_length; i++) LOG_T(PHY,"%x.",i,DLSCH_pdu[i]);// FIXME this code is broken (number of arguments) LOG_T(PHY,"\n"); */ #endif #endif if (abstraction_flag == 0) { start_meas(&phy_vars_eNB->dlsch_encoding_stats); dlsch_encoding(DLSCH_pdu, &phy_vars_eNB->lte_frame_parms, num_pdcch_symbols, phy_vars_eNB->dlsch_eNB_SI, phy_vars_eNB->proc[sched_subframe].frame_tx,subframe, &phy_vars_eNB->dlsch_rate_matching_stats, &phy_vars_eNB->dlsch_turbo_encoding_stats, &phy_vars_eNB->dlsch_interleaving_stats); stop_meas(&phy_vars_eNB->dlsch_encoding_stats); start_meas(&phy_vars_eNB->dlsch_scrambling_stats); dlsch_scrambling(&phy_vars_eNB->lte_frame_parms, 0, phy_vars_eNB->dlsch_eNB_SI, get_G(&phy_vars_eNB->lte_frame_parms, phy_vars_eNB->dlsch_eNB_SI->harq_processes[0]->nb_rb, phy_vars_eNB->dlsch_eNB_SI->harq_processes[0]->rb_alloc, get_Qm(phy_vars_eNB->dlsch_eNB_SI->harq_processes[0]->mcs), 1, num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe), 0, subframe<<1); stop_meas(&phy_vars_eNB->dlsch_scrambling_stats); start_meas(&phy_vars_eNB->dlsch_modulation_stats); // for (sect_id=0;sect_id<number_of_cards;sect_id++) re_allocated = dlsch_modulation(phy_vars_eNB->lte_eNB_common_vars.txdataF[0], AMP, subframe, &phy_vars_eNB->lte_frame_parms, num_pdcch_symbols, phy_vars_eNB->dlsch_eNB_SI, (LTE_eNB_DLSCH_t *)NULL); stop_meas(&phy_vars_eNB->dlsch_modulation_stats); } #ifdef PHY_ABSTRACTION else { start_meas(&phy_vars_eNB->dlsch_encoding_stats); dlsch_encoding_emul(phy_vars_eNB, DLSCH_pdu, phy_vars_eNB->dlsch_eNB_SI); stop_meas(&phy_vars_eNB->dlsch_encoding_stats); } #endif phy_vars_eNB->dlsch_eNB_SI->active = 0; } // Check for RA activity if (phy_vars_eNB->dlsch_eNB_ra->active == 1) { #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %"PRIu8"][RAPROC] Frame %d, subframe %d, RA active, filling RAR:\n", phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, subframe); #endif input_buffer_length = phy_vars_eNB->dlsch_eNB_ra->harq_processes[0]->TBS/8; #ifdef OPENAIR2 int16_t crnti = mac_xface->fill_rar(phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, phy_vars_eNB->proc[sched_subframe].frame_tx, dlsch_input_buffer, phy_vars_eNB->lte_frame_parms.N_RB_UL, input_buffer_length); /* for (i=0;i<input_buffer_length;i++) LOG_T(PHY,"%x.",dlsch_input_buffer[i]); LOG_T(PHY,"\n"); */ if (crnti!=0) UE_id = add_ue(crnti,phy_vars_eNB); else UE_id = -1; if (UE_id==-1) { LOG_W(PHY,"[eNB] Max user count reached.\n"); //mac_xface->macphy_exit("[PHY][eNB] Max user count reached.\n"); mac_xface->cancel_ra_proc(phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, phy_vars_eNB->proc[sched_subframe].frame_tx, crnti); } else { phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].mode = RA_RESPONSE; // Initialize indicator for first SR (to be cleared after ConnectionSetup is acknowledged) phy_vars_eNB->first_sr[(uint32_t)UE_id] = 1; generate_eNB_ulsch_params_from_rar(dlsch_input_buffer, phy_vars_eNB->proc[sched_subframe].frame_tx, (subframe), phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id], &phy_vars_eNB->lte_frame_parms); phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_active = 1; get_Msg3_alloc(&phy_vars_eNB->lte_frame_parms, subframe, phy_vars_eNB->proc[sched_subframe].frame_tx, &phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame, &phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe); LOG_I(PHY,"[eNB][RAPROC] Frame %d subframe %d, Activated Msg3 demodulation for UE %"PRId8" in frame %"PRIu32", subframe %"PRIu8"\n", phy_vars_eNB->proc[sched_subframe].frame_tx, subframe, UE_id, phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame, phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe); #else for (i=0; i<input_buffer_length; i++) dlsch_input_buffer[i]= (unsigned char) i; //(taus()&0xff); dlsch_input_buffer[1] = (phy_vars_eNB->eNB_UE_stats[0].UE_timing_offset)>>(2+4); // 7 MSBs of timing advance + divide by 4 dlsch_input_buffer[2] = ((phy_vars_eNB->eNB_UE_stats[0].UE_timing_offset)<<(4-2))&0xf0; // 4 LSBs of timing advance + divide by 4 //LOG_I(PHY,"UE %d: timing_offset = %d\n",UE_id,phy_vars_eNB->eNB_UE_stats[0].UE_timing_offset); #endif #if defined(SMBV) && !defined(EXMIMO) // Configures the data source of allocation (allocation is configured by DCI) if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) { msg("[SMBV] Frame %3d, Configuring RA payload in SF %d alloc %"PRIu8"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,(smbv_frame_cnt*10) + (subframe),smbv_alloc_cnt); smbv_configure_datalist_for_alloc(smbv_fname, smbv_alloc_cnt++, (smbv_frame_cnt*10) + (subframe), dlsch_input_buffer, input_buffer_length); } #endif #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %"PRIu8"][RAPROC] Frame %d, subframe %d: Calling generate_dlsch (RA) with input size = %"PRIu16",Msg3 frame %"PRIu32", Msg3 subframe %"PRIu8"\n", phy_vars_eNB->Mod_id, phy_vars_eNB->proc[sched_subframe].frame_tx, subframe,input_buffer_length, phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame, phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe); #endif if (abstraction_flag == 0) { dlsch_encoding(dlsch_input_buffer, &phy_vars_eNB->lte_frame_parms, num_pdcch_symbols, phy_vars_eNB->dlsch_eNB_ra, phy_vars_eNB->proc[sched_subframe].frame_tx,subframe, &phy_vars_eNB->dlsch_rate_matching_stats, &phy_vars_eNB->dlsch_turbo_encoding_stats, &phy_vars_eNB->dlsch_interleaving_stats); // phy_vars_eNB->dlsch_eNB_ra->rnti = RA_RNTI; dlsch_scrambling(&phy_vars_eNB->lte_frame_parms, 0, phy_vars_eNB->dlsch_eNB_ra, get_G(&phy_vars_eNB->lte_frame_parms, phy_vars_eNB->dlsch_eNB_ra->harq_processes[0]->nb_rb, phy_vars_eNB->dlsch_eNB_ra->harq_processes[0]->rb_alloc, get_Qm(phy_vars_eNB->dlsch_eNB_ra->harq_processes[0]->mcs), 1, num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe), 0, subframe<<1); // for (sect_id=0;sect_id<number_of_cards;sect_id++) re_allocated = dlsch_modulation(phy_vars_eNB->lte_eNB_common_vars.txdataF[0], AMP, subframe, &phy_vars_eNB->lte_frame_parms, num_pdcch_symbols, phy_vars_eNB->dlsch_eNB_ra, (LTE_eNB_DLSCH_t *)NULL); } #ifdef PHY_ABSTRACTION else { dlsch_encoding_emul(phy_vars_eNB, dlsch_input_buffer, phy_vars_eNB->dlsch_eNB_ra); } #endif LOG_D(PHY,"[eNB %"PRIu8"][RAPROC] Frame %d subframe %d Deactivating DLSCH RA\n",phy_vars_eNB->Mod_id, phy_vars_eNB->proc[sched_subframe].frame_tx,subframe); #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d, DLSCH (RA) re_allocated = %"PRIu16"\n",phy_vars_eNB->Mod_id, phy_vars_eNB->proc[sched_subframe].frame_tx, subframe, re_allocated); #endif #ifdef OPENAIR2 } //max user count #endif phy_vars_eNB->dlsch_eNB_ra->active = 0; } // Now scan UE specific DLSCH for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { if ((phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0])&& (phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->rnti>0)&& (phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->active == 1)) { harq_pid = phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->current_harq_pid; input_buffer_length = phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->TBS/8; #ifdef DEBUG_PHY_PROC LOG_D(PHY, "[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d, subframe %d: Generating PDSCH/DLSCH with input size = %"PRIu16", G %d, nb_rb %"PRIu16", mcs %"PRIu8", pmi_alloc %"PRIx16", rv %"PRIu8" (round %"PRIu8")\n", phy_vars_eNB->Mod_id, phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->rnti,harq_pid, phy_vars_eNB->proc[sched_subframe].frame_tx, subframe, input_buffer_length, get_G(&phy_vars_eNB->lte_frame_parms, phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->nb_rb, phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->rb_alloc, get_Qm(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs), phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->Nl, num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe), phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->nb_rb, phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs, pmi2hex_2Ar1(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->pmi_alloc), phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->rvidx, phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->round); #endif #if defined(MESSAGE_CHART_GENERATOR_PHY) MSC_LOG_TX_MESSAGE( MSC_PHY_ENB,MSC_PHY_UE, NULL,0, "%05u:%02u PDSCH/DLSCH input size = %"PRIu16", G %d, nb_rb %"PRIu16", mcs %"PRIu8", pmi_alloc %"PRIx16", rv %"PRIu8" (round %"PRIu8")", phy_vars_eNB->proc[sched_subframe].frame_tx, subframe, input_buffer_length, get_G(&phy_vars_eNB->lte_frame_parms, phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->nb_rb, phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->rb_alloc, get_Qm(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs), phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->Nl, num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe), phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->nb_rb, phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs, pmi2hex_2Ar1(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->pmi_alloc), phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->rvidx, phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->round); #endif phy_vars_eNB->eNB_UE_stats[(uint8_t)UE_id].dlsch_sliding_cnt++; if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->harq_processes[harq_pid]->round == 0) { phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].dlsch_trials[harq_pid][0]++; #ifdef OPENAIR2 DLSCH_pdu = mac_xface->get_dlsch_sdu(phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, phy_vars_eNB->proc[sched_subframe].frame_tx, phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->rnti, 0); phy_vars_eNB->eNB_UE_stats[UE_id].total_TBS_MAC += phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->TBS; #else DLSCH_pdu = DLSCH_pdu_tmp; for (i=0; i<input_buffer_length; i++) DLSCH_pdu[i] = (unsigned char)(taus()&0xff); #endif #if defined(SMBV) && !defined(EXMIMO) // Configures the data source of allocation (allocation is configured by DCI) if (smbv_is_config_frame(phy_vars_eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) { msg("[SMBV] Frame %3d, Configuring PDSCH payload in SF %d alloc %"PRIu8"\n",phy_vars_eNB->proc[sched_subframe].frame_tx,(smbv_frame_cnt*10) + (subframe),smbv_alloc_cnt); smbv_configure_datalist_for_user(smbv_fname, UE_id+1, DLSCH_pdu, input_buffer_length); } #endif #ifdef DEBUG_PHY_PROC #ifdef DEBUG_DLSCH LOG_T(PHY,"eNB DLSCH SDU: \n"); for (i=0; i<phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->TBS>>3; i++) LOG_T(PHY,"%"PRIx8".",DLSCH_pdu[i]); LOG_T(PHY,"\n"); #endif #endif } else { phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].dlsch_trials[harq_pid][phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->round]++; #ifdef DEBUG_PHY_PROC #ifdef DEBUG_DLSCH LOG_D(PHY,"[eNB] This DLSCH is a retransmission\n"); #endif #endif } if (abstraction_flag==0) { // 36-212 start_meas(&phy_vars_eNB->dlsch_encoding_stats); dlsch_encoding(DLSCH_pdu, &phy_vars_eNB->lte_frame_parms, num_pdcch_symbols, phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0], phy_vars_eNB->proc[sched_subframe].frame_tx,subframe, &phy_vars_eNB->dlsch_rate_matching_stats, &phy_vars_eNB->dlsch_turbo_encoding_stats, &phy_vars_eNB->dlsch_interleaving_stats); stop_meas(&phy_vars_eNB->dlsch_encoding_stats); // 36-211 start_meas(&phy_vars_eNB->dlsch_scrambling_stats); dlsch_scrambling(&phy_vars_eNB->lte_frame_parms, 0, phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0], get_G(&phy_vars_eNB->lte_frame_parms, phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->nb_rb, phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->rb_alloc, get_Qm(phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs), phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->Nl, num_pdcch_symbols,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe), 0, subframe<<1); stop_meas(&phy_vars_eNB->dlsch_scrambling_stats); start_meas(&phy_vars_eNB->dlsch_modulation_stats); //for (sect_id=0;sect_id<number_of_cards;sect_id++) { /* if ((phy_vars_eNB->transmission_mode[(uint8_t)UE_id] == 5) && (phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->dl_power_off == 0)) amp = (int16_t)(((int32_t)AMP*(int32_t)ONE_OVER_SQRT2_Q15)>>15); else*/ // amp = AMP; // if (UE_id == 1) // LOG_I(PHY,"[MYEMOS] MCS_i %d\n", phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[harq_pid]->mcs); re_allocated = dlsch_modulation(phy_vars_eNB->lte_eNB_common_vars.txdataF[0], AMP, subframe, &phy_vars_eNB->lte_frame_parms, num_pdcch_symbols, phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0], phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][1]); stop_meas(&phy_vars_eNB->dlsch_modulation_stats); } #ifdef PHY_ABSTRACTION else { start_meas(&phy_vars_eNB->dlsch_encoding_stats); dlsch_encoding_emul(phy_vars_eNB, DLSCH_pdu, phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]); stop_meas(&phy_vars_eNB->dlsch_encoding_stats); } #endif phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->active = 0; //mac_xface->macphy_exit("first dlsch transmitted\n"); } else if ((phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0])&& (phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->rnti>0)&& (phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->active == 0)) { // clear subframe TX flag since UE is not scheduled for PDSCH in this subframe (so that we don't look for PUCCH later) phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->subframe_tx[subframe]=0; #ifdef DEBUG_PHY_PROC //LOG_D(PHY,"[eNB %d] DCI: Clearing subframe_tx for subframe %d, UE %d\n",phy_vars_eNB->Mod_id,subframe,UE_id); #endif } } // if we have PHICH to generate // printf("[PHY][eNB] Frame %d subframe %d Checking for phich\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe); if (is_phich_subframe(&phy_vars_eNB->lte_frame_parms,subframe)) { #ifdef DEBUG_PHY_PROC // LOG_D(PHY,"[eNB %d] Frame %d, subframe %d: Calling generate_phich_top\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx, subframe); #endif // for (sect_id=0;sect_id<number_of_cards;sect_id++) { generate_phich_top(phy_vars_eNB, sched_subframe, AMP, 0, abstraction_flag); } #ifdef EMOS phy_procedures_emos_eNB_TX(subframe, phy_vars_eNB); #endif #if !(defined(EXMIMO) || defined(OAI_USRP) || defined (CPRIGW)) if (abstraction_flag==0) { start_meas(&phy_vars_eNB->ofdm_mod_stats); do_OFDM_mod(phy_vars_eNB->lte_eNB_common_vars.txdataF[0], phy_vars_eNB->lte_eNB_common_vars.txdata[0], phy_vars_eNB->proc[sched_subframe].frame_tx,subframe<<1, &phy_vars_eNB->lte_frame_parms); do_OFDM_mod(phy_vars_eNB->lte_eNB_common_vars.txdataF[0], phy_vars_eNB->lte_eNB_common_vars.txdata[0], phy_vars_eNB->proc[sched_subframe].frame_tx,1+(subframe<<1), &phy_vars_eNB->lte_frame_parms); stop_meas(&phy_vars_eNB->ofdm_mod_stats); } #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX,0); stop_meas(&phy_vars_eNB->phy_proc_tx); } void process_Msg3(PHY_VARS_eNB *phy_vars_eNB,uint8_t sched_subframe,uint8_t UE_id, uint8_t harq_pid) { // this prepares the demodulation of the first PUSCH of a new user, containing Msg3 int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx; int frame = phy_vars_eNB->proc[sched_subframe].frame_rx; LOG_D(PHY,"[eNB %d][RAPROC] frame %d : subframe %d : process_Msg3 UE_id %d (active %d, subframe %d, frame %d)\n", phy_vars_eNB->Mod_id, frame,subframe, UE_id,phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_active, phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe, phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame); phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_flag = 0; if ((phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_active == 1) && (phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe == subframe) && (phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame == (uint32_t)frame)) { // harq_pid = 0; phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_active = 0; phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_flag = 1; phy_vars_eNB->ulsch_eNB[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag=1; LOG_D(PHY,"[eNB %d][RAPROC] frame %d, subframe %d: Setting subframe_scheduling_flag (Msg3) for UE %d\n", phy_vars_eNB->Mod_id, frame,subframe,UE_id); } } // This function retrieves the harq_pid of the corresponding DLSCH process // and updates the error statistics of the DLSCH based on the received ACK // info from UE along with the round index. It also performs the fine-grain // rate-adaptation based on the error statistics derived from the ACK/NAK process void process_HARQ_feedback(uint8_t UE_id, uint8_t sched_subframe, PHY_VARS_eNB *phy_vars_eNB, uint8_t pusch_flag, uint8_t *pucch_payload, uint8_t pucch_sel, uint8_t SR_payload) { uint8_t dl_harq_pid[8],dlsch_ACK[8],dl_subframe; LTE_eNB_DLSCH_t *dlsch = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]; LTE_eNB_UE_stats *ue_stats = &phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id]; LTE_DL_eNB_HARQ_t *dlsch_harq_proc; uint8_t subframe_m4,M,m; int mp; int all_ACKed=1,nb_alloc=0,nb_ACK=0; int frame = phy_vars_eNB->proc[sched_subframe].frame_rx; int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx; int harq_pid = subframe2harq_pid( &phy_vars_eNB->lte_frame_parms,frame,subframe); if (phy_vars_eNB->lte_frame_parms.frame_type == FDD) { //FDD subframe_m4 = (subframe<4) ? subframe+6 : subframe-4; dl_harq_pid[0] = dlsch->harq_ids[subframe_m4]; M=1; if (pusch_flag == 1) { dlsch_ACK[0] = phy_vars_eNB->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[0]; if (dlsch->subframe_tx[subframe_m4]==1) LOG_D(PHY,"[eNB %d] Frame %d: Received ACK/NAK %d on PUSCH for subframe %d\n",phy_vars_eNB->Mod_id, frame,dlsch_ACK[0],subframe_m4); } else { dlsch_ACK[0] = pucch_payload[0]; LOG_D(PHY,"[eNB %d] Frame %d: Received ACK/NAK %d on PUCCH for subframe %d\n",phy_vars_eNB->Mod_id, frame,dlsch_ACK[0],subframe_m4); /* if (dlsch_ACK[0]==0) AssertFatal(0,"Exiting on NAK on PUCCH\n"); */ } #if defined(MESSAGE_CHART_GENERATOR_PHY) MSC_LOG_RX_MESSAGE( MSC_PHY_ENB,MSC_PHY_UE, NULL,0, "%05u:%02u %s received %s rnti %x harq id %u tx SF %u", frame,subframe, (pusch_flag == 1)?"PUSCH":"PUCCH", (dlsch_ACK[0])?"ACK":"NACK", dlsch->rnti, dl_harq_pid[0], subframe_m4 ); #endif } else { // TDD Handle M=1,2 cases only M=ul_ACK_subframe2_M(&phy_vars_eNB->lte_frame_parms, subframe); // Now derive ACK information for TDD if (pusch_flag == 1) { // Do PUSCH ACK/NAK first // detect missing DAI //FK: this code is just a guess //RK: not exactly, yes if scheduled from PHICH (i.e. no DCI format 0) // otherwise, it depends on how many of the PDSCH in the set are scheduled, we can leave it like this, // but we have to adapt the code below. For example, if only one out of 2 are scheduled, only 1 bit o_ACK is used dlsch_ACK[0] = phy_vars_eNB->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[0]; dlsch_ACK[1] = (phy_vars_eNB->pucch_config_dedicated[UE_id].tdd_AckNackFeedbackMode == bundling) ?phy_vars_eNB->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[0]:phy_vars_eNB->ulsch_eNB[(uint8_t)UE_id]->harq_processes[harq_pid]->o_ACK[1]; // printf("UE %d: ACK %d,%d\n",UE_id,dlsch_ACK[0],dlsch_ACK[1]); } else { // PUCCH ACK/NAK if ((SR_payload == 1)&&(pucch_sel!=2)) { // decode Table 7.3 if multiplexing and SR=1 nb_ACK = 0; if (M == 2) { if ((pucch_payload[0] == 1) && (pucch_payload[1] == 1)) // b[0],b[1] nb_ACK = 1; else if ((pucch_payload[0] == 1) && (pucch_payload[1] == 0)) nb_ACK = 2; } else if (M == 3) { if ((pucch_payload[0] == 1) && (pucch_payload[1] == 1)) nb_ACK = 1; else if ((pucch_payload[0] == 1) && (pucch_payload[1] == 0)) nb_ACK = 2; else if ((pucch_payload[0] == 0) && (pucch_payload[1] == 1)) nb_ACK = 3; } } else if (pucch_sel == 2) { // bundling or M=1 // printf("*** (%d,%d)\n",pucch_payload[0],pucch_payload[1]); dlsch_ACK[0] = pucch_payload[0]; dlsch_ACK[1] = pucch_payload[0]; } else { // multiplexing with no SR, this is table 10.1 if (M==1) dlsch_ACK[0] = pucch_payload[0]; else if (M==2) { if (((pucch_sel == 1) && (pucch_payload[0] == 1) && (pucch_payload[1] == 1)) || ((pucch_sel == 0) && (pucch_payload[0] == 0) && (pucch_payload[1] == 1))) dlsch_ACK[0] = 1; else dlsch_ACK[0] = 0; if (((pucch_sel == 1) && (pucch_payload[0] == 1) && (pucch_payload[1] == 1)) || ((pucch_sel == 1) && (pucch_payload[0] == 0) && (pucch_payload[1] == 0))) dlsch_ACK[1] = 1; else dlsch_ACK[1] = 0; } } } } // handle case where positive SR was transmitted with multiplexing if ((SR_payload == 1)&&(pucch_sel!=2)&&(pusch_flag == 0)) { nb_alloc = 0; for (m=0; m<M; m++) { dl_subframe = ul_ACK_subframe2_dl_subframe(&phy_vars_eNB->lte_frame_parms, subframe, m); if (dlsch->subframe_tx[dl_subframe]==1) nb_alloc++; } if (nb_alloc == nb_ACK) all_ACKed = 1; else all_ACKed = 0; // printf("nb_alloc %d, all_ACKed %d\n",nb_alloc,all_ACKed); } for (m=0,mp=-1; m<M; m++) { dl_subframe = ul_ACK_subframe2_dl_subframe(&phy_vars_eNB->lte_frame_parms, subframe, m); if (dlsch->subframe_tx[dl_subframe]==1) { if (pusch_flag == 1) mp++; else mp = m; dl_harq_pid[m] = dlsch->harq_ids[dl_subframe]; if ((pucch_sel != 2)&&(pusch_flag == 0)) { // multiplexing if ((SR_payload == 1)&&(all_ACKed == 1)) dlsch_ACK[m] = 1; else dlsch_ACK[m] = 0; } if (dl_harq_pid[m]<dlsch->Mdlharq) { dlsch_harq_proc = dlsch->harq_processes[dl_harq_pid[m]]; #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d][PDSCH %x/%d] subframe %d, status %d, round %d (mcs %d, rv %d, TBS %d)\n",phy_vars_eNB->Mod_id, dlsch->rnti,dl_harq_pid[m],dl_subframe, dlsch_harq_proc->status,dlsch_harq_proc->round, dlsch->harq_processes[dl_harq_pid[m]]->mcs, dlsch->harq_processes[dl_harq_pid[m]]->rvidx, dlsch->harq_processes[dl_harq_pid[m]]->TBS); if (dlsch_harq_proc->status==DISABLED) LOG_E(PHY,"dlsch_harq_proc is disabled? \n"); #endif if ((dl_harq_pid[m]<dlsch->Mdlharq) && (dlsch_harq_proc->status == ACTIVE)) { // dl_harq_pid of DLSCH is still active // msg("[PHY] eNB %d Process %d is active (%d)\n",phy_vars_eNB->Mod_id,dl_harq_pid[m],dlsch_ACK[m]); if ( dlsch_ACK[mp]==0) { // Received NAK #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d][PDSCH %x/%d] M = %d, m= %d, mp=%d NAK Received in round %d, requesting retransmission\n",phy_vars_eNB->Mod_id, dlsch->rnti,dl_harq_pid[m],M,m,mp,dlsch_harq_proc->round); #endif if (dlsch_harq_proc->round == 0) ue_stats->dlsch_NAK_round0++; ue_stats->dlsch_NAK[dl_harq_pid[m]][dlsch_harq_proc->round]++; // then Increment DLSCH round index dlsch_harq_proc->round++; if (dlsch_harq_proc->round == dlsch->Mdlharq) { // This was the last round for DLSCH so reset round and increment l2_error counter #ifdef DEBUG_PHY_PROC LOG_W(PHY,"[eNB %d][PDSCH %x/%d] DLSCH retransmissions exhausted, dropping packet\n",phy_vars_eNB->Mod_id, dlsch->rnti,dl_harq_pid[m]); #endif #if defined(MESSAGE_CHART_GENERATOR_PHY) MSC_LOG_EVENT(MSC_PHY_ENB, "0 HARQ DLSCH Failed RNTI %"PRIx16" round %u", dlsch->rnti, dlsch_harq_proc->round); #endif dlsch_harq_proc->round = 0; ue_stats->dlsch_l2_errors[dl_harq_pid[m]]++; dlsch_harq_proc->status = SCH_IDLE; dlsch->harq_ids[dl_subframe] = dlsch->Mdlharq; } } else { #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d][PDSCH %x/%d] ACK Received in round %d, resetting process\n",phy_vars_eNB->Mod_id, dlsch->rnti,dl_harq_pid[m],dlsch_harq_proc->round); #endif ue_stats->dlsch_ACK[dl_harq_pid[m]][dlsch_harq_proc->round]++; // Received ACK so set round to 0 and set dlsch_harq_pid IDLE dlsch_harq_proc->round = 0; dlsch_harq_proc->status = SCH_IDLE; dlsch->harq_ids[dl_subframe] = dlsch->Mdlharq; ue_stats->total_TBS = ue_stats->total_TBS + phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[dl_harq_pid[m]]->TBS; /* ue_stats->total_transmitted_bits = ue_stats->total_transmitted_bits + phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->harq_processes[dl_harq_pid[m]]->TBS; */ } // Do fine-grain rate-adaptation for DLSCH if (ue_stats->dlsch_NAK_round0 > dlsch->error_threshold) { if (ue_stats->dlsch_mcs_offset == 1) ue_stats->dlsch_mcs_offset=0; else ue_stats->dlsch_mcs_offset=-1; } #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[process_HARQ_feedback] Frame %d Setting round to %d for pid %d (subframe %d)\n",frame, dlsch_harq_proc->round,dl_harq_pid[m],subframe); #endif // Clear NAK stats and adjust mcs offset // after measurement window timer expires if (ue_stats->dlsch_sliding_cnt == dlsch->ra_window_size) { if ((ue_stats->dlsch_mcs_offset == 0) && (ue_stats->dlsch_NAK_round0 < 2)) ue_stats->dlsch_mcs_offset = 1; if ((ue_stats->dlsch_mcs_offset == 1) && (ue_stats->dlsch_NAK_round0 > 2)) ue_stats->dlsch_mcs_offset = 0; if ((ue_stats->dlsch_mcs_offset == 0) && (ue_stats->dlsch_NAK_round0 > 2)) ue_stats->dlsch_mcs_offset = -1; if ((ue_stats->dlsch_mcs_offset == -1) && (ue_stats->dlsch_NAK_round0 < 2)) ue_stats->dlsch_mcs_offset = 0; ue_stats->dlsch_NAK_round0 = 0; ue_stats->dlsch_sliding_cnt = 0; } } } } } } void get_n1_pucch_eNB(PHY_VARS_eNB *phy_vars_eNB, uint8_t UE_id, uint8_t sched_subframe, int16_t *n1_pucch0, int16_t *n1_pucch1, int16_t *n1_pucch2, int16_t *n1_pucch3) { LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->lte_frame_parms; uint8_t nCCE0,nCCE1; int sf; int frame = phy_vars_eNB->proc[sched_subframe].frame_rx; int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx; if (frame_parms->frame_type == FDD ) { sf = (subframe<4) ? (subframe+6) : (subframe-4); // printf("n1_pucch_eNB: subframe %d, nCCE %d\n",sf,phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[sf]); if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[sf]>0) { *n1_pucch0 = frame_parms->pucch_config_common.n1PUCCH_AN + phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[sf]; *n1_pucch1 = -1; } else { *n1_pucch0 = -1; *n1_pucch1 = -1; } } else { switch (frame_parms->tdd_config) { case 1: // DL:S:UL:UL:DL:DL:S:UL:UL:DL if (subframe == 2) { // ACK subframes 5 and 6 /* if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[6]>0) { nCCE1 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[6]; *n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN; } else *n1_pucch1 = -1;*/ if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[5]>0) { nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[5]; *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN; } else *n1_pucch0 = -1; *n1_pucch1 = -1; } else if (subframe == 3) { // ACK subframe 9 if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[9]>0) { nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[9]; *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 +frame_parms->pucch_config_common.n1PUCCH_AN; } else *n1_pucch0 = -1; *n1_pucch1 = -1; } else if (subframe == 7) { // ACK subframes 0 and 1 //harq_ack[0].nCCE; //harq_ack[1].nCCE; if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[0]>0) { nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[0]; *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 + frame_parms->pucch_config_common.n1PUCCH_AN; } else *n1_pucch0 = -1; *n1_pucch1 = -1; } else if (subframe == 8) { // ACK subframes 4 //harq_ack[4].nCCE; if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[4]>0) { nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[4]; *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 + frame_parms->pucch_config_common.n1PUCCH_AN; } else *n1_pucch0 = -1; *n1_pucch1 = -1; } else { LOG_D(PHY,"[eNB %d] frame %d: phy_procedures_lte.c: get_n1pucch, illegal subframe %d for tdd_config %d\n", phy_vars_eNB->Mod_id, frame, subframe,frame_parms->tdd_config); return; } break; case 3: // DL:S:UL:UL:UL:DL:DL:DL:DL:DL if (subframe == 2) { // ACK subframes 5,6 and 1 (S in frame-2), forget about n-11 for the moment (S-subframe) if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[6]>0) { nCCE1 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[6]; *n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN; } else *n1_pucch1 = -1; if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[5]>0) { nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[5]; *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN; } else *n1_pucch0 = -1; } else if (subframe == 3) { // ACK subframes 7 and 8 LOG_D(PHY,"get_n1_pucch_eNB : subframe 3, subframe_tx[7] %d, subframe_tx[8] %d\n", phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[7],phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[8]); if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[8]>0) { nCCE1 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[8]; *n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN; LOG_D(PHY,"nCCE1 %d, n1_pucch1 %d\n",nCCE1,*n1_pucch1); } else *n1_pucch1 = -1; if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[7]>0) { nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[7]; *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 +frame_parms->pucch_config_common.n1PUCCH_AN; LOG_D(PHY,"nCCE0 %d, n1_pucch0 %d\n",nCCE0,*n1_pucch0); } else *n1_pucch0 = -1; } else if (subframe == 4) { // ACK subframes 9 and 0 if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[0]>0) { nCCE1 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[0]; *n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN; } else *n1_pucch1 = -1; if (phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->subframe_tx[9]>0) { nCCE0 = phy_vars_eNB->dlsch_eNB[(uint32_t)UE_id][0]->nCCE[9]; *n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0 +frame_parms->pucch_config_common.n1PUCCH_AN; } else *n1_pucch0 = -1; } else { LOG_D(PHY,"[eNB %d] Frame %d: phy_procedures_lte.c: get_n1pucch, illegal subframe %d for tdd_config %d\n", phy_vars_eNB->Mod_id,frame,subframe,frame_parms->tdd_config); return; } break; } // switch tdd_config // Don't handle the case M>2 *n1_pucch2 = -1; *n1_pucch3 = -1; } } void prach_procedures(PHY_VARS_eNB *phy_vars_eNB,uint8_t sched_subframe,uint8_t abstraction_flag) { uint16_t preamble_energy_list[64],preamble_delay_list[64]; uint16_t preamble_max,preamble_energy_max; uint16_t i; int8_t UE_id; int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx; int frame = phy_vars_eNB->proc[sched_subframe].frame_rx; uint8_t CC_id = phy_vars_eNB->CC_id; memset(&preamble_energy_list[0],0,64*sizeof(uint16_t)); memset(&preamble_delay_list[0],0,64*sizeof(uint16_t)); if (abstraction_flag == 0) { LOG_D(PHY,"[eNB %d][RAPROC] Frame %d, Subframe %d : PRACH RX Signal Power : %d dBm\n",phy_vars_eNB->Mod_id, frame,subframe,dB_fixed(signal_energy(&phy_vars_eNB->lte_eNB_common_vars.rxdata[0][0][subframe*phy_vars_eNB->lte_frame_parms.samples_per_tti],512)) - phy_vars_eNB->rx_total_gain_eNB_dB); // LOG_I(PHY,"[eNB %d][RAPROC] PRACH: rootSequenceIndex %d, prach_ConfigIndex %d, zeroCorrelationZoneConfig %d, highSpeedFlag %d, prach_FreqOffset %d\n",phy_vars_eNB->Mod_id,phy_vars_eNB->lte_frame_parms.prach_config_common.rootSequenceIndex,phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex, phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig,phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag,phy_vars_eNB->lte_frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset); rx_prach(phy_vars_eNB, subframe, preamble_energy_list, preamble_delay_list, frame, 0); } else { for (UE_id=0; UE_id<NB_UE_INST; UE_id++) { LOG_D(PHY,"[RAPROC] UE_id %d (%p), generate_prach %d, UE RSI %d, eNB RSI %d preamble index %d\n", UE_id,PHY_vars_UE_g[UE_id][CC_id],PHY_vars_UE_g[UE_id][CC_id]->generate_prach, PHY_vars_UE_g[UE_id][CC_id]->lte_frame_parms.prach_config_common.rootSequenceIndex, phy_vars_eNB->lte_frame_parms.prach_config_common.rootSequenceIndex, PHY_vars_UE_g[UE_id][CC_id]->prach_PreambleIndex); if ((PHY_vars_UE_g[UE_id][CC_id]->generate_prach==1) && (PHY_vars_UE_g[UE_id][CC_id]->lte_frame_parms.prach_config_common.rootSequenceIndex == phy_vars_eNB->lte_frame_parms.prach_config_common.rootSequenceIndex) ) { preamble_energy_list[PHY_vars_UE_g[UE_id][CC_id]->prach_PreambleIndex] = 800; preamble_delay_list[PHY_vars_UE_g[UE_id][CC_id]->prach_PreambleIndex] = 5; } } } preamble_energy_max = preamble_energy_list[0]; preamble_max = 0; for (i=1; i<64; i++) { if (preamble_energy_max < preamble_energy_list[i]) { preamble_energy_max = preamble_energy_list[i]; preamble_max = i; } } #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[RAPROC] Most likely preamble %d, energy %d dB delay %d\n", preamble_max, preamble_energy_list[preamble_max], preamble_delay_list[preamble_max]); #endif if (preamble_energy_list[preamble_max] > 580) { /* write_output("prach_ifft0.m","prach_t0",prach_ifft[0],2048,1,1); write_output("prach_rx0.m","prach_rx0",&phy_vars_eNB->lte_eNB_common_vars.rxdata[0][0][subframe*phy_vars_eNB->lte_frame_parms.samples_per_tti],6144+792,1,1); write_output("prach_rxF0.m","prach_rxF0",phy_vars_eNB->lte_eNB_prach_vars.rxsigF[0],24576,1,1); mac_xface->macphy_exit("Exiting for PRACH debug\n"); */ UE_id = find_next_ue_index(phy_vars_eNB); if (UE_id>=0) { phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].UE_timing_offset = preamble_delay_list[preamble_max]&0x1FFF; //limit to 13 (=11+2) bits //phy_vars_eNb->eNB_UE_stats[(uint32_t)UE_id].mode = PRACH; phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].sector = 0; LOG_I(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure (UE_id %d) with preamble %d, energy %d.%d dB, delay %d\n", phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, frame, subframe, UE_id, preamble_max, preamble_energy_max/10, preamble_energy_max%10, preamble_delay_list[preamble_max]); #ifdef OPENAIR2 uint8_t update_TA=4; switch (phy_vars_eNB->lte_frame_parms.N_RB_DL) { case 6: update_TA = 16; break; case 25: update_TA = 4; break; case 50: update_TA = 2; break; case 100: update_TA = 1; break; } mac_xface->initiate_ra_proc(phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, frame, preamble_max, preamble_delay_list[preamble_max]*update_TA, 0,subframe,0); #endif } else { MSC_LOG_EVENT(MSC_PHY_ENB, "0 RA Failed add user, too many"); LOG_I(PHY,"[eNB %d][RAPROC] frame %d, subframe %d: Unable to add user, max user count reached\n", phy_vars_eNB->Mod_id,frame, subframe); } } } void ulsch_decoding_procedures(unsigned char subframe, unsigned int i, PHY_VARS_eNB *phy_vars_eNB, unsigned char abstraction_flag) { UNUSED(subframe); UNUSED(i); UNUSED(phy_vars_eNB); UNUSED(abstraction_flag); LOG_D(PHY,"ulsch_decoding_procedures not yet implemented. should not be called"); } void phy_procedures_eNB_RX(const unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_eNB,const uint8_t abstraction_flag,const relaying_type_t r_type) { //RX processing UNUSED(r_type); uint32_t l, ret=0,i,j,k; uint32_t sect_id=0; uint32_t harq_pid, harq_idx, round; uint8_t SR_payload = 0,*pucch_payload=NULL,pucch_payload0[2]= {0,0},pucch_payload1[2]= {0,0}; int16_t n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3; uint8_t do_SR = 0; uint8_t pucch_sel = 0; int32_t metric0=0,metric1=0; ANFBmode_t bundling_flag; PUCCH_FMT_t format; uint8_t nPRS; // uint8_t two_ues_connected = 0; uint8_t pusch_active = 0; LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_eNB->lte_frame_parms; int sync_pos; uint16_t rnti=0; uint8_t access_mode; int num_active_cba_groups; const int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx; const int frame = phy_vars_eNB->proc[sched_subframe].frame_rx; AssertFatal(sched_subframe < NUM_ENB_THREADS, "Bad sched_subframe %d", sched_subframe); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX,1); start_meas(&phy_vars_eNB->phy_proc_rx); #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_RX(%d)\n",phy_vars_eNB->Mod_id,frame, subframe); #endif /* #ifdef OAI_USRP for (aa=0;aa<phy_vars_eNB->lte_frame_parms.nb_antennas_rx;aa++) rescale(&phy_vars_eNB->lte_eNB_common_vars.rxdata[0][aa][subframe*phy_vars_eNB->lte_frame_parms.samples_per_tti], phy_vars_eNB->lte_frame_parms.samples_per_tti); #endif */ phy_vars_eNB->rb_mask_ul[0]=0; phy_vars_eNB->rb_mask_ul[1]=0; phy_vars_eNB->rb_mask_ul[2]=0; phy_vars_eNB->rb_mask_ul[3]=0; if (abstraction_flag == 0) { remove_7_5_kHz(phy_vars_eNB,subframe<<1); remove_7_5_kHz(phy_vars_eNB,(subframe<<1)+1); } // check if we have to detect PRACH first if (is_prach_subframe(&phy_vars_eNB->lte_frame_parms,frame,subframe)>0) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,1); prach_procedures(phy_vars_eNB,sched_subframe,abstraction_flag); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0); } if (abstraction_flag == 0) { start_meas(&phy_vars_eNB->ofdm_demod_stats); for (l=0; l<phy_vars_eNB->lte_frame_parms.symbols_per_tti/2; l++) { // for (sect_id=0;sect_id<number_of_cards;sect_id++) { slot_fep_ul(&phy_vars_eNB->lte_frame_parms, &phy_vars_eNB->lte_eNB_common_vars, l, subframe<<1, 0, 0 ); slot_fep_ul(&phy_vars_eNB->lte_frame_parms, &phy_vars_eNB->lte_eNB_common_vars, l, (subframe<<1)+1, 0, 0 ); } stop_meas(&phy_vars_eNB->ofdm_demod_stats); } sect_id = 0; /* for (UE_id=0;UE_id<NUMBER_OF_UE_MAX;UE_id++) { if ((phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].mode>PRACH) && (last_slot%2==1)) { #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d] frame %d, slot %d: Doing SRS estimation and measurements for UE_id %d (UE_mode %d)\n", phy_vars_eNB->Mod_id, phy_vars_eNB->proc[sched_subframe].frame_tx, last_slot, UE_id,phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].mode); #endif for (sect_id=0;sect_id<number_of_cards;sect_id++) { lte_srs_channel_estimation(&phy_vars_eNB->lte_frame_parms, &phy_vars_eNB->lte_eNB_common_vars, &phy_vars_eNB->lte_eNB_srs_vars[(uint32_t)UE_id], &phy_vars_eNB->soundingrs_ul_config_dedicated[(uint32_t)UE_id], last_slot>>1, sect_id); lte_eNB_srs_measurements(phy_vars_eNB, sect_id, UE_id, 1); #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d] frame %d, slot %d: UE_id %d, sect_id %d: RX RSSI %d (from SRS)\n", phy_vars_eNB->Mod_id, phy_vars_eNB->proc[sched_subframe].frame_tx, last_slot, UE_id,sect_id, phy_vars_eNB->PHY_measurements_eNB[sect_id].rx_rssi_dBm[(uint32_t)UE_id]); #endif } sect_id=0; #ifdef USER_MODE //write_output("srs_est0.m","srsest0",phy_vars_eNB->lte_eNB_common_vars.srs_ch_estimates[0][0],512,1,1); //write_output("srs_est1.m","srsest1",phy_vars_eNB->lte_eNB_common_vars.srs_ch_estimates[0][1],512,1,1); #endif //msg("timing advance in\n"); sync_pos = lte_est_timing_advance(&phy_vars_eNB->lte_frame_parms, &phy_vars_eNB->lte_eNB_srs_vars[(uint32_t)UE_id], §_id, phy_vars_eNB->first_run_timing_advance[(uint32_t)UE_id], number_of_cards, 24576); //msg("timing advance out\n"); //phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].UE_timing_offset = sync_pos - phy_vars_eNB->lte_frame_parms.nb_prefix_samples/8; phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].UE_timing_offset = 0; phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].sector = sect_id; #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d] frame %d, slot %d: user %d in sector %d: timing_advance = %d\n", phy_vars_eNB->Mod_id, phy_vars_eNB->proc[sched_subframe].frame_tx, last_slot, UE_id, sect_id, phy_vars_eNB->eNB_UE_stats[(uint32_t)UE_id].UE_timing_offset); #endif } } else { } */ // Check for active processes in current subframe harq_pid = subframe2harq_pid(&phy_vars_eNB->lte_frame_parms, frame,subframe); pusch_active = 0; // reset the cba flag used for collision detection for (i=0; i < NUM_MAX_CBA_GROUP; i++) { phy_vars_eNB->cba_last_reception[i]=0; } // LOG_I(PHY,"subframe %d: nPRS %d\n",last_slot>>1,phy_vars_eNB->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[last_slot-1]); for (i=0; i<NUMBER_OF_UE_MAX; i++) { /* if ((i == 1) && (phy_vars_eNB->cooperation_flag > 0) && (two_ues_connected == 1)) break; */ #ifdef OPENAIR2 if (phy_vars_eNB->eNB_UE_stats[i].mode == RA_RESPONSE) process_Msg3(phy_vars_eNB,sched_subframe,i,harq_pid); #endif /* #ifdef DEBUG_PHY_PROC if (phy_vars_eNB->ulsch_eNB[i]) { LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d, subframe %d rnti %x, alloc %d, Msg3 %d\n",phy_vars_eNB->Mod_id, harq_pid,frame,subframe, (phy_vars_eNB->ulsch_eNB[i]->rnti), (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->subframe_scheduling_flag), (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag) ); } #endif */ if ((phy_vars_eNB->ulsch_eNB[i]) && (phy_vars_eNB->ulsch_eNB[i]->rnti>0) && (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->subframe_scheduling_flag==1)) { pusch_active = 1; round = phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round; for (int rb=0; rb<=phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb; rb++) { int rb2 = rb+phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->first_rb; phy_vars_eNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31)); } #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d Scheduling PUSCH/ULSCH Reception for rnti %x (UE_id %d)\n", phy_vars_eNB->Mod_id,harq_pid, frame,subframe,phy_vars_eNB->ulsch_eNB[i]->rnti,i); #endif #ifdef DEBUG_PHY_PROC if (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag == 1) { LOG_D(PHY,"[eNB %d] frame %d, subframe %d: Scheduling ULSCH Reception for Msg3 in Sector %d\n", phy_vars_eNB->Mod_id, frame, subframe, phy_vars_eNB->eNB_UE_stats[i].sector); } else { LOG_D(PHY,"[eNB %d] frame %d, subframe %d: Scheduling ULSCH Reception for UE %d Mode %s sect_id %d\n", phy_vars_eNB->Mod_id, frame, subframe, i, mode_string[phy_vars_eNB->eNB_UE_stats[i].mode], phy_vars_eNB->eNB_UE_stats[i].sector); } #endif nPRS = phy_vars_eNB->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1]; phy_vars_eNB->ulsch_eNB[i]->cyclicShift = (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->n_DMRS2 + phy_vars_eNB->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift + nPRS)%12; if (frame_parms->frame_type == FDD ) { int sf = (subframe<4) ? (subframe+6) : (subframe-4); if (phy_vars_eNB->dlsch_eNB[i][0]->subframe_tx[sf]>0) { // we have downlink transmission phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->O_ACK = 1; } else { phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->O_ACK = 0; } } #ifdef DEBUG_PHY_PROC LOG_D(PHY, "[eNB %d][PUSCH %d] Frame %d Subframe %d Demodulating PUSCH: dci_alloc %d, rar_alloc %d, round %d, first_rb %d, nb_rb %d, mcs %d, TBS %d, rv %d, cyclic_shift %d (n_DMRS2 %d, cyclicShift_common %d, nprs %d), O_ACK %d \n", phy_vars_eNB->Mod_id,harq_pid,frame,subframe, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->dci_alloc, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->rar_alloc, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->first_rb, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->mcs, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->rvidx, phy_vars_eNB->ulsch_eNB[i]->cyclicShift, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->n_DMRS2, phy_vars_eNB->lte_frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift, nPRS, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->O_ACK); #endif start_meas(&phy_vars_eNB->ulsch_demodulation_stats); if (abstraction_flag==0) { rx_ulsch(phy_vars_eNB, sched_subframe, phy_vars_eNB->eNB_UE_stats[i].sector, // this is the effective sector id i, phy_vars_eNB->ulsch_eNB, 0); } #ifdef PHY_ABSTRACTION else { rx_ulsch_emul(phy_vars_eNB, subframe, phy_vars_eNB->eNB_UE_stats[i].sector, // this is the effective sector id i); } #endif stop_meas(&phy_vars_eNB->ulsch_demodulation_stats); start_meas(&phy_vars_eNB->ulsch_decoding_stats); if (abstraction_flag == 0) { ret = ulsch_decoding(phy_vars_eNB, i, sched_subframe, 0, // control_only_flag phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->V_UL_DAI, 0); } #ifdef PHY_ABSTRACTION else { ret = ulsch_decoding_emul(phy_vars_eNB, sched_subframe, i, &rnti); } #endif stop_meas(&phy_vars_eNB->ulsch_decoding_stats); #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n", phy_vars_eNB->Mod_id,harq_pid, frame,subframe, phy_vars_eNB->ulsch_eNB[i]->rnti, dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[0]), dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[1]), phy_vars_eNB->eNB_UE_stats[i].UL_rssi[0], phy_vars_eNB->eNB_UE_stats[i].UL_rssi[1], phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[0], phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[1], phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0], phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1], ret); #endif //DEBUG_PHY_PROC /* if ((two_ues_connected==1) && (phy_vars_eNB->cooperation_flag==2)) { for (j=0;j<phy_vars_eNB->lte_frame_parms.nb_antennas_rx;j++) { phy_vars_eNB->eNB_UE_stats[i].UL_rssi[j] = dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power_0[j]) - phy_vars_eNB->rx_total_gain_eNB_dB; phy_vars_eNB->eNB_UE_stats[i+1].UL_rssi[j] = dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power_1[j]) - phy_vars_eNB->rx_total_gain_eNB_dB; } #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d] Frame %d subframe %d: ULSCH %d RX power UE0 (%d,%d) dB RX power UE1 (%d,%d)\n", phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,last_slot>>1,i, dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power_0[0]), dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power_0[1]), dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power_1[0]), dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power_1[1])); #endif } else { */ //compute the expected ULSCH RX power (for the stats) phy_vars_eNB->ulsch_eNB[(uint32_t)i]->harq_processes[harq_pid]->delta_TF = get_hundred_times_delta_IF_eNB(phy_vars_eNB,i,harq_pid, 0); // 0 means bw_factor is not considered //dump_ulsch(phy_vars_eNB, sched_subframe, i); phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_pid][phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round]++; #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d harq_pid %d Clearing subframe_scheduling_flag\n", phy_vars_eNB->Mod_id,harq_pid,frame,subframe,i,harq_pid); #endif phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->subframe_scheduling_flag=0; if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->cqi_crc_status == 1) { #ifdef DEBUG_PHY_PROC //if (((phy_vars_eNB->proc[sched_subframe].frame_tx%10) == 0) || (phy_vars_eNB->proc[sched_subframe].frame_tx < 50)) print_CQI(phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->uci_format,0,phy_vars_eNB->lte_frame_parms.N_RB_DL); #endif extract_CQI(phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->uci_format, &phy_vars_eNB->eNB_UE_stats[i], phy_vars_eNB->lte_frame_parms.N_RB_DL, &rnti, &access_mode); phy_vars_eNB->eNB_UE_stats[i].rank = phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_RI[0]; } if (ret == (1+MAX_TURBO_ITERATIONS)) { /* if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round>0) { dump_ulsch(phy_vars_eNB, sched_subframe, i); mac_xface->macphy_exit("retransmission in error"); } */ phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors[harq_pid][phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round]++; phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 1; phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_ACK = 0; phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round++; LOG_D(PHY,"[eNB][PUSCH %d] Increasing to round %d\n",harq_pid,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round); if (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag == 1) { LOG_I(PHY,"[eNB %d/%d][RAPROC] frame %d, subframe %d, UE %d: Error receiving ULSCH (Msg3), round %d/%d\n", phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, frame,subframe, i, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round-1, phy_vars_eNB->lte_frame_parms.maxHARQ_Msg3Tx-1); LOG_I(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n", phy_vars_eNB->Mod_id,harq_pid, frame,subframe, phy_vars_eNB->ulsch_eNB[i]->rnti, dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[0]), dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[1]), phy_vars_eNB->eNB_UE_stats[i].UL_rssi[0], phy_vars_eNB->eNB_UE_stats[i].UL_rssi[1], phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[0], phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[1], phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0], phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1], ret); if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round == phy_vars_eNB->lte_frame_parms.maxHARQ_Msg3Tx) { LOG_I(PHY,"[eNB %d][RAPROC] maxHARQ_Msg3Tx reached, abandoning RA procedure for UE %d\n", phy_vars_eNB->Mod_id, i); phy_vars_eNB->eNB_UE_stats[i].mode = PRACH; #ifdef OPENAIR2 mac_xface->cancel_ra_proc(phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, frame, phy_vars_eNB->eNB_UE_stats[i].crnti); #endif remove_ue(phy_vars_eNB->eNB_UE_stats[i].crnti,phy_vars_eNB,abstraction_flag); phy_vars_eNB->ulsch_eNB[(uint32_t)i]->Msg3_active = 0; //phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 0; } else { // activate retransmission for Msg3 (signalled to UE PHY by PHICH (not MAC/DCI) phy_vars_eNB->ulsch_eNB[(uint32_t)i]->Msg3_active = 1; get_Msg3_alloc_ret(&phy_vars_eNB->lte_frame_parms, subframe, frame, &phy_vars_eNB->ulsch_eNB[i]->Msg3_frame, &phy_vars_eNB->ulsch_eNB[i]->Msg3_subframe); }/* LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:",frame,subframe, harq_pid,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3); for (j=0;j<phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3;j++) printf("%x.",phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->c[0][j]); printf("\n"); */ // dump_ulsch(phy_vars_eNB,sched_subframe,i); //#ifndef EXMIMO_IOT LOG_W(PHY,"[eNB] Frame %d, Subframe %d: Msg3 in error, i = %d \n", frame,subframe,i); //#else //mac_exit_wrapper("Msg3 error"); //#endif } // This is Msg3 error else { //normal ULSCH LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n", phy_vars_eNB->Mod_id,harq_pid, frame,subframe, i, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round-1, phy_vars_eNB->ulsch_eNB[i]->Mdlharq, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0], phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1]); #if defined(MESSAGE_CHART_GENERATOR_PHY) MSC_LOG_RX_DISCARDED_MESSAGE( MSC_PHY_ENB,MSC_PHY_UE, NULL,0, "%05u:%02u ULSCH received rnti %x harq id %u round %d", frame,subframe, phy_vars_eNB->ulsch_eNB[i]->rnti,harq_pid, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round-1 ); #endif /* LOG_T(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:\n",frame,subframe, harq_pid,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3); if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->c[0]!=NULL){ for (j=0;j<phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3;j++) LOG_T(PHY,"%x.",phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->c[0][j]); LOG_T(PHY,"\n"); } */ // dump_ulsch(phy_vars_eNB,sched_subframe,i); //mac_exit_wrapper("ULSCH error"); if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round== phy_vars_eNB->ulsch_eNB[i]->Mdlharq) { LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d ULSCH Mdlharq %d reached\n", phy_vars_eNB->Mod_id,harq_pid, frame,subframe, i, phy_vars_eNB->ulsch_eNB[i]->Mdlharq); phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round=0; phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active=0; phy_vars_eNB->eNB_UE_stats[i].ulsch_errors[harq_pid]++; phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors++; //dump_ulsch(phy_vars_eNB, sched_subframe, i); } } } // ulsch in error else { if (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag == 1) { LOG_I(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d ULSCH received, setting round to 0, PHICH ACK\n", phy_vars_eNB->Mod_id,harq_pid, frame,subframe); LOG_I(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d RNTI %x RX power (%d,%d) RSSI (%d,%d) N0 (%d,%d) dB ACK (%d,%d), decoding iter %d\n", phy_vars_eNB->Mod_id,harq_pid, frame,subframe, phy_vars_eNB->ulsch_eNB[i]->rnti, dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[0]), dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[1]), phy_vars_eNB->eNB_UE_stats[i].UL_rssi[0], phy_vars_eNB->eNB_UE_stats[i].UL_rssi[1], phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[0], phy_vars_eNB->PHY_measurements_eNB->n0_power_dB[1], phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0], phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1], ret); } #if defined(MESSAGE_CHART_GENERATOR_PHY) MSC_LOG_RX_MESSAGE( MSC_PHY_ENB,MSC_PHY_UE, NULL,0, "%05u:%02u ULSCH received rnti %x harq id %u", frame,subframe, phy_vars_eNB->ulsch_eNB[i]->rnti,harq_pid ); #endif for (j=0; j<phy_vars_eNB->lte_frame_parms.nb_antennas_rx; j++) //this is the RSSI per RB phy_vars_eNB->eNB_UE_stats[i].UL_rssi[j] = dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[j]* (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb*12)/ phy_vars_eNB->lte_frame_parms.ofdm_symbol_size) - phy_vars_eNB->rx_total_gain_eNB_dB - hundred_times_log10_NPRB[phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb-1]/100 - get_hundred_times_delta_IF_eNB(phy_vars_eNB,i,harq_pid, 0)/100; /* dB_fixed(phy_vars_eNB->lte_eNB_pusch_vars[i]->ulsch_power[j]*phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb) - phy_vars_eNB->rx_total_gain_eNB_dB - hundred_times_log10_NPRB[phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->nb_rb-1]/100 - get_hundred_times_delta_IF_eNB(phy_vars_eNB,i,harq_pid, 0)/100;*/ phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 1; phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_ACK = 1; phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round = 0; phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors = 0; if (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag == 1) { #ifdef OPENAIR2 #ifdef DEBUG_PHY_PROC LOG_I(PHY,"[eNB %d][RAPROC] Frame %d Terminating ra_proc for harq %d, UE %d\n", phy_vars_eNB->Mod_id, frame,harq_pid,i); #endif mac_xface->rx_sdu(phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, frame,subframe, phy_vars_eNB->ulsch_eNB[i]->rnti, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3, harq_pid, &phy_vars_eNB->ulsch_eNB[i]->Msg3_flag); // false msg3 detection by MAC: empty PDU if (phy_vars_eNB->ulsch_eNB[i]->Msg3_flag == 0 ) { phy_vars_eNB->eNB_UE_stats[i].mode = PRACH; mac_xface->cancel_ra_proc(phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, frame, phy_vars_eNB->eNB_UE_stats[i].crnti); remove_ue(phy_vars_eNB->eNB_UE_stats[i].crnti,phy_vars_eNB,abstraction_flag); phy_vars_eNB->ulsch_eNB[(uint32_t)i]->Msg3_active = 0; } /* mac_xface->terminate_ra_proc(phy_vars_eNB->Mod_id, frame, phy_vars_eNB->ulsch_eNB[i]->rnti, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3); */ #endif phy_vars_eNB->eNB_UE_stats[i].mode = PUSCH; phy_vars_eNB->ulsch_eNB[i]->Msg3_flag = 0; #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d][RAPROC] Frame %d : RX Subframe %d Setting UE %d mode to PUSCH\n",phy_vars_eNB->Mod_id,frame,subframe,i); #endif //DEBUG_PHY_PROC for (k=0; k<8; k++) { //harq_processes for (j=0; j<phy_vars_eNB->dlsch_eNB[i][0]->Mdlharq; j++) { phy_vars_eNB->eNB_UE_stats[i].dlsch_NAK[k][j]=0; phy_vars_eNB->eNB_UE_stats[i].dlsch_ACK[k][j]=0; phy_vars_eNB->eNB_UE_stats[i].dlsch_trials[k][j]=0; } phy_vars_eNB->eNB_UE_stats[i].dlsch_l2_errors[k]=0; phy_vars_eNB->eNB_UE_stats[i].ulsch_errors[k]=0; phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors=0; for (j=0; j<phy_vars_eNB->ulsch_eNB[i]->Mdlharq; j++) { phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[k][j]=0; phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts_last[k][j]=0; phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors[k][j]=0; phy_vars_eNB->eNB_UE_stats[i].ulsch_round_fer[k][j]=0; } } phy_vars_eNB->eNB_UE_stats[i].dlsch_sliding_cnt=0; phy_vars_eNB->eNB_UE_stats[i].dlsch_NAK_round0=0; phy_vars_eNB->eNB_UE_stats[i].dlsch_mcs_offset=0; //mac_xface->macphy_exit("Mode PUSCH. Exiting.\n"); } else { #ifdef DEBUG_PHY_PROC #ifdef DEBUG_ULSCH LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:",frame,subframe, harq_pid,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3); for (j=0; j<phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3; j++) LOG_T(PHY,"%x.",phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b[j]); LOG_T(PHY,"\n"); #endif #endif //dump_ulsch(phy_vars_eNB,sched_subframe,i); #ifdef OPENAIR2 // if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->calibration_flag == 0) { mac_xface->rx_sdu(phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, frame,subframe, phy_vars_eNB->ulsch_eNB[i]->rnti, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3, harq_pid, NULL); //} /* else { // Retrieve calibration information and do whatever LOG_D(PHY,"[eNB][Auto-Calibration] Frame %d, Subframe %d : ULSCH PDU (RX) %d bytes\n",phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3); } */ #ifdef LOCALIZATION start_meas(&phy_vars_eNB->localization_stats); aggregate_eNB_UE_localization_stats(phy_vars_eNB, i, frame, subframe, get_hundred_times_delta_IF_eNB(phy_vars_eNB,i,harq_pid, 1)/100); stop_meas(&phy_vars_eNB->localization_stats); #endif #endif } // estimate timing advance for MAC if (abstraction_flag == 0) { sync_pos = lte_est_timing_advance_pusch(phy_vars_eNB,i,sched_subframe); phy_vars_eNB->eNB_UE_stats[i].timing_advance_update = sync_pos - phy_vars_eNB->lte_frame_parms.nb_prefix_samples/4; //to check } #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d] frame %d, subframe %d: user %d in sector %d: timing advance = %d\n", phy_vars_eNB->Mod_id, frame, subframe, i, sect_id, phy_vars_eNB->eNB_UE_stats[i].timing_advance_update); #endif } // ulsch not in error // process HARQ feedback #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d, Processing HARQ feedback for UE %d (after PUSCH)\n",phy_vars_eNB->Mod_id, phy_vars_eNB->dlsch_eNB[i][0]->rnti, frame,subframe, i); #endif process_HARQ_feedback(i, sched_subframe, phy_vars_eNB, 1, // pusch_flag 0, 0, 0); #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d] Frame %d subframe %d, sect %d: received ULSCH harq_pid %d for UE %d, ret = %d, CQI CRC Status %d, ACK %d,%d, ulsch_errors %d/%d\n", phy_vars_eNB->Mod_id,frame,subframe, phy_vars_eNB->eNB_UE_stats[i].sector, harq_pid, i, ret, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->cqi_crc_status, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[0], phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_ACK[1], phy_vars_eNB->eNB_UE_stats[i].ulsch_errors[harq_pid], phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_pid][0]); #endif } #ifdef PUCCH else if ((phy_vars_eNB->dlsch_eNB[i][0]) && (phy_vars_eNB->dlsch_eNB[i][0]->rnti>0)) { // check for PUCCH // check SR availability do_SR = is_SR_subframe(phy_vars_eNB,i,sched_subframe); // do_SR = 0; // Now ACK/NAK // First check subframe_tx flag for earlier subframes get_n1_pucch_eNB(phy_vars_eNB, i, sched_subframe, &n1_pucch0, &n1_pucch1, &n1_pucch2, &n1_pucch3); LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d, subframe %d Checking for PUCCH (%d,%d,%d,%d) SR %d\n", phy_vars_eNB->Mod_id,phy_vars_eNB->dlsch_eNB[i][0]->rnti, frame,subframe, n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,do_SR); if ((n1_pucch0==-1) && (n1_pucch1==-1) && (do_SR==0)) { // no TX PDSCH that have to be checked and no SR for this UE_id } else { // otherwise we have some PUCCH detection to do // Null out PUCCH PRBs for noise measurement switch(phy_vars_eNB->lte_frame_parms.N_RB_UL) { case 6: phy_vars_eNB->rb_mask_ul[0] |= (0x1 | (1<<5)); //position 5 break; case 15: phy_vars_eNB->rb_mask_ul[0] |= (0x1 | (1<<14)); // position 14 break; case 25: phy_vars_eNB->rb_mask_ul[0] |= (0x1 | (1<<24)); // position 24 break; case 50: phy_vars_eNB->rb_mask_ul[0] |= 0x1; phy_vars_eNB->rb_mask_ul[1] |= (1<<17); // position 49 (49-32) break; case 75: phy_vars_eNB->rb_mask_ul[0] |= 0x1; phy_vars_eNB->rb_mask_ul[2] |= (1<<10); // position 74 (74-64) break; case 100: phy_vars_eNB->rb_mask_ul[0] |= 0x1; phy_vars_eNB->rb_mask_ul[3] |= (1<<3); // position 99 (99-96) break; default: LOG_E(PHY,"Unknown number for N_RB_UL %d\n",phy_vars_eNB->lte_frame_parms.N_RB_UL); break; } if (do_SR == 1) { phy_vars_eNB->eNB_UE_stats[i].sr_total++; if (abstraction_flag == 0) metric0 = rx_pucch(phy_vars_eNB, pucch_format1, i, phy_vars_eNB->scheduling_request_config[i].sr_PUCCH_ResourceIndex, 0, // n2_pucch 0, // shortened format, should be use_srs flag, later &SR_payload, subframe, PUCCH1_THRES); #ifdef PHY_ABSTRACTION else { metric0 = rx_pucch_emul(phy_vars_eNB, i, pucch_format1, 0, &SR_payload, sched_subframe); LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking SR (UE SR %d/%d)\n",phy_vars_eNB->Mod_id, phy_vars_eNB->ulsch_eNB[i]->rnti,frame,subframe,SR_payload,phy_vars_eNB->scheduling_request_config[i].sr_PUCCH_ResourceIndex); } #endif if (SR_payload == 1) { LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Got SR for PUSCH, transmitting to MAC\n",phy_vars_eNB->Mod_id, phy_vars_eNB->ulsch_eNB[i]->rnti,frame,subframe); phy_vars_eNB->eNB_UE_stats[i].sr_received++; if (phy_vars_eNB->first_sr[i] == 1) { // this is the first request for uplink after Connection Setup, so clear HARQ process 0 use for Msg4 phy_vars_eNB->first_sr[i] = 0; phy_vars_eNB->dlsch_eNB[i][0]->harq_processes[0]->round=0; phy_vars_eNB->dlsch_eNB[i][0]->harq_processes[0]->status=SCH_IDLE; LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d First SR\n", phy_vars_eNB->Mod_id, phy_vars_eNB->ulsch_eNB[i]->rnti,frame,subframe); } #ifdef OPENAIR2 mac_xface->SR_indication(phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, frame, phy_vars_eNB->dlsch_eNB[i][0]->rnti,subframe); #endif } }// do_SR==1 if ((n1_pucch0==-1) && (n1_pucch1==-1)) { // just check for SR } else if (phy_vars_eNB->lte_frame_parms.frame_type==FDD) { // FDD // if SR was detected, use the n1_pucch from SR, else use n1_pucch0 n1_pucch0 = (SR_payload==1) ? phy_vars_eNB->scheduling_request_config[i].sr_PUCCH_ResourceIndex:n1_pucch0; LOG_D(PHY,"Demodulating PUCCH for ACK/NAK: n1_pucch0 %d (%d), SR_payload %d\n",n1_pucch0,phy_vars_eNB->scheduling_request_config[i].sr_PUCCH_ResourceIndex,SR_payload); if (abstraction_flag == 0) metric0 = rx_pucch(phy_vars_eNB, pucch_format1a, i, (uint16_t)n1_pucch0, 0, //n2_pucch 1, // shortened format pucch_payload0, subframe, PUCCH1a_THRES); else { #ifdef PHY_ABSTRACTION metric0 = rx_pucch_emul(phy_vars_eNB,i, pucch_format1a, 0, pucch_payload0, subframe); #endif } #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d pucch1a (FDD) payload %d (metric %d)\n", phy_vars_eNB->Mod_id, phy_vars_eNB->dlsch_eNB[i][0]->rnti, frame,subframe, pucch_payload0[0],metric0); #endif process_HARQ_feedback(i,sched_subframe,phy_vars_eNB, 0,// pusch_flag pucch_payload0, 2, SR_payload); } // FDD else { //TDD bundling_flag = phy_vars_eNB->pucch_config_dedicated[i].tdd_AckNackFeedbackMode; // fix later for 2 TB case and format1b if ((frame_parms->frame_type==FDD) || (bundling_flag==bundling) || ((frame_parms->frame_type==TDD)&&(frame_parms->tdd_config==1)&&((subframe!=2)||(subframe!=7)))) { format = pucch_format1a; // msg("PUCCH 1a\n"); } else { format = pucch_format1b; // msg("PUCCH 1b\n"); } // if SR was detected, use the n1_pucch from SR if (SR_payload==1) { #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d with SR\n",phy_vars_eNB->Mod_id, phy_vars_eNB->dlsch_eNB[i][0]->rnti, frame,subframe, n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,format); #endif if (abstraction_flag == 0) metric0 = rx_pucch(phy_vars_eNB, format, i, phy_vars_eNB->scheduling_request_config[i].sr_PUCCH_ResourceIndex, 0, //n2_pucch 1, // shortened format pucch_payload0, subframe, PUCCH1a_THRES); else { #ifdef PHY_ABSTRACTION metric0 = rx_pucch_emul(phy_vars_eNB,i, format, 0, pucch_payload0, subframe); #endif } } else { //using n1_pucch0/n1_pucch1 resources #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d Checking ACK/NAK (%d,%d,%d,%d) format %d\n",phy_vars_eNB->Mod_id, phy_vars_eNB->dlsch_eNB[i][0]->rnti, frame,subframe, n1_pucch0,n1_pucch1,n1_pucch2,n1_pucch3,format); #endif metric0=0; metric1=0; // Check n1_pucch0 metric if (n1_pucch0 != -1) { if (abstraction_flag == 0) metric0 = rx_pucch(phy_vars_eNB, format, i, (uint16_t)n1_pucch0, 0, // n2_pucch 1, // shortened format pucch_payload0, subframe, PUCCH1a_THRES); else { #ifdef PHY_ABSTRACTION metric0 = rx_pucch_emul(phy_vars_eNB,i, format, 0, pucch_payload0, subframe); #endif } } // Check n1_pucch1 metric if (n1_pucch1 != -1) { if (abstraction_flag == 0) metric1 = rx_pucch(phy_vars_eNB, format, i, (uint16_t)n1_pucch1, 0, //n2_pucch 1, // shortened format pucch_payload1, subframe, PUCCH1a_THRES); else { #ifdef PHY_ABSTRACTION metric1 = rx_pucch_emul(phy_vars_eNB,i, format, 1, pucch_payload1, subframe); #endif } } } if (SR_payload == 1) { pucch_payload = pucch_payload0; if (bundling_flag == bundling) pucch_sel = 2; } else if (bundling_flag == multiplexing) { // multiplexing + no SR pucch_payload = (metric1>metric0) ? pucch_payload1 : pucch_payload0; pucch_sel = (metric1>metric0) ? 1 : 0; } else { // bundling + no SR if (n1_pucch1 != -1) pucch_payload = pucch_payload1; else if (n1_pucch0 != -1) pucch_payload = pucch_payload0; pucch_sel = 2; // indicate that this is a bundled ACK/NAK } #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d ACK/NAK metric 0 %d, metric 1 %d, sel %d, (%d,%d)\n",phy_vars_eNB->Mod_id, phy_vars_eNB->dlsch_eNB[i][0]->rnti, frame,subframe, metric0,metric1,pucch_sel,pucch_payload[0],pucch_payload[1]); #endif process_HARQ_feedback(i,sched_subframe,phy_vars_eNB, 0,// pusch_flag pucch_payload, pucch_sel, SR_payload); } } } // PUCCH processing #endif //PUCCH if ((frame % 100 == 0) && (subframe == 4)) { for (harq_idx=0; harq_idx<8; harq_idx++) { for (round=0; round<phy_vars_eNB->ulsch_eNB[i]->Mdlharq; round++) { if ((phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_idx][round] - phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts_last[harq_idx][round]) != 0) { phy_vars_eNB->eNB_UE_stats[i].ulsch_round_fer[harq_idx][round] = (100*(phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors[harq_idx][round] - phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors_last[harq_idx][round]))/ (phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_idx][round] - phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts_last[harq_idx][round]); } else { phy_vars_eNB->eNB_UE_stats[i].ulsch_round_fer[harq_idx][round] = 0; } phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts_last[harq_idx][round] = phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[harq_idx][round]; phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors_last[harq_idx][round] = phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors[harq_idx][round]; } } } if ((frame % 100 == 0) && (subframe==4)) { phy_vars_eNB->eNB_UE_stats[i].dlsch_bitrate = (phy_vars_eNB->eNB_UE_stats[i].total_TBS - phy_vars_eNB->eNB_UE_stats[i].total_TBS_last); phy_vars_eNB->eNB_UE_stats[i].total_TBS_last = phy_vars_eNB->eNB_UE_stats[i].total_TBS; } num_active_cba_groups = phy_vars_eNB->ulsch_eNB[i]->num_active_cba_groups; /*if (num_active_cba_groups > 0 ) LOG_D(PHY,"[eNB] last slot %d trying cba transmission decoding UE %d num_grps %d rnti %x flag %d\n", last_slot, i, num_active_cba_groups,phy_vars_eNB->ulsch_eNB[i]->cba_rnti[i%num_active_cba_groups], phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->subframe_cba_scheduling_flag ); */ if ((phy_vars_eNB->ulsch_eNB[i]) && (num_active_cba_groups > 0) && (phy_vars_eNB->ulsch_eNB[i]->cba_rnti[i%num_active_cba_groups]>0) && (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->subframe_cba_scheduling_flag==1)) { rnti=0; #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d Checking PUSCH/ULSCH CBA Reception for UE %d with cba rnti %x mode %s\n", phy_vars_eNB->Mod_id,harq_pid, frame,subframe, i, (uint16_t)phy_vars_eNB->ulsch_eNB[i]->cba_rnti[i%num_active_cba_groups],mode_string[phy_vars_eNB->eNB_UE_stats[i].mode]); #endif if (abstraction_flag==0) { rx_ulsch(phy_vars_eNB, sched_subframe, phy_vars_eNB->eNB_UE_stats[i].sector, // this is the effective sector id i, phy_vars_eNB->ulsch_eNB, 0); } #ifdef PHY_ABSTRACTION else { rx_ulsch_emul(phy_vars_eNB, subframe, phy_vars_eNB->eNB_UE_stats[i].sector, // this is the effective sector id i); } #endif if (abstraction_flag == 0) { ret = ulsch_decoding(phy_vars_eNB, i, sched_subframe, 0, // control_only_flag phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->V_UL_DAI, 0); } #ifdef PHY_ABSTRACTION else { ret = ulsch_decoding_emul(phy_vars_eNB, sched_subframe, i, &rnti); } #endif if (phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->cqi_crc_status == 1) { #ifdef DEBUG_PHY_PROC //if (((phy_vars_eNB->proc[sched_subframe].frame_tx%10) == 0) || (phy_vars_eNB->proc[sched_subframe].frame_tx < 50)) print_CQI(phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->uci_format,0,phy_vars_eNB->lte_frame_parms.N_RB_DL); #endif access_mode = UNKNOWN_ACCESS; extract_CQI(phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->uci_format, &phy_vars_eNB->eNB_UE_stats[i], phy_vars_eNB->lte_frame_parms.N_RB_DL, &rnti, &access_mode); phy_vars_eNB->eNB_UE_stats[i].rank = phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->o_RI[0]; } /* LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d harq_pid %d resetting the sched_subframeuling_flag, total cba groups %d %d\n", phy_vars_eNB->Mod_id,harq_pid,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,i,harq_pid, phy_vars_eNB->ulsch_eNB[i]->num_active_cba_groups,num_active_cba_groups); */ phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->subframe_cba_scheduling_flag=0; phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->status= SCH_IDLE; if ((num_active_cba_groups > 0) && // (i % num_active_cba_groups == 0) && // this ue is used a a template for the CBA (i + num_active_cba_groups < NUMBER_OF_UE_MAX) && (phy_vars_eNB->ulsch_eNB[i+num_active_cba_groups]->cba_rnti[i%num_active_cba_groups] > 0 ) && (phy_vars_eNB->ulsch_eNB[i+num_active_cba_groups]->num_active_cba_groups> 0)) { #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d harq_pid %d resetting the subframe_scheduling_flag for Ue %d cba groups %d members\n", phy_vars_eNB->Mod_id,harq_pid,frame,subframe,i,harq_pid, i+num_active_cba_groups, i%phy_vars_eNB->ulsch_eNB[i]->num_active_cba_groups); #endif phy_vars_eNB->ulsch_eNB[i+num_active_cba_groups]->harq_processes[harq_pid]->subframe_cba_scheduling_flag=1; phy_vars_eNB->ulsch_eNB[i+num_active_cba_groups]->harq_processes[harq_pid]->status= CBA_ACTIVE; phy_vars_eNB->ulsch_eNB[i+num_active_cba_groups]->harq_processes[harq_pid]->TBS=phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS; } if (ret == (1+MAX_TURBO_ITERATIONS)) { phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors[harq_pid][phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round]++; phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 1; phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_ACK = 0; phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round++; } // ulsch in error else { LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d ULSCH received, setting round to 0, PHICH ACK\n", phy_vars_eNB->Mod_id,harq_pid, frame,subframe); phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_active = 1; phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->phich_ACK = 1; phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->round = 0; phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors = 0; #ifdef DEBUG_PHY_PROC #ifdef DEBUG_ULSCH LOG_D(PHY,"[eNB] Frame %d, Subframe %d : ULSCH SDU (RX harq_pid %d) %d bytes:", frame,subframe, harq_pid,phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3); for (j=0; j<phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3; j++) LOG_T(PHY,"%x.",phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b[j]); LOG_T(PHY,"\n"); #endif #endif if (access_mode > UNKNOWN_ACCESS) { LOG_D(PHY,"[eNB %d] Frame %d, Subframe %d : received ULSCH SDU from CBA transmission, UE (%d,%x), CBA (group %d, rnti %x)\n", phy_vars_eNB->Mod_id, frame,subframe, i, phy_vars_eNB->ulsch_eNB[i]->rnti, i % phy_vars_eNB->ulsch_eNB[i]->num_active_cba_groups, phy_vars_eNB->ulsch_eNB[i]->cba_rnti[i%num_active_cba_groups]); // detect if there is a CBA collision if (phy_vars_eNB->cba_last_reception[i%num_active_cba_groups] == 0 ) { mac_xface->rx_sdu(phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, frame,subframe, phy_vars_eNB->ulsch_eNB[i]->rnti, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->b, phy_vars_eNB->ulsch_eNB[i]->harq_processes[harq_pid]->TBS>>3, harq_pid, NULL); phy_vars_eNB->cba_last_reception[i%num_active_cba_groups]+=1;//(subframe); } else { if (phy_vars_eNB->cba_last_reception[i%num_active_cba_groups] == 1 ) LOG_N(PHY,"[eNB%d] Frame %d subframe %d : first CBA collision detected \n ", phy_vars_eNB->Mod_id,frame,subframe); LOG_N(PHY,"[eNB%d] Frame %d subframe %d : CBA collision set SR for UE %d in group %d \n ", phy_vars_eNB->Mod_id,frame,subframe, phy_vars_eNB->cba_last_reception[i%num_active_cba_groups],i%num_active_cba_groups ); phy_vars_eNB->cba_last_reception[i%num_active_cba_groups]+=1; mac_xface->SR_indication(phy_vars_eNB->Mod_id, phy_vars_eNB->CC_id, frame, phy_vars_eNB->dlsch_eNB[i][0]->rnti,subframe); } } } // ULSCH CBA not in error } } // loop i=0 ... NUMBER_OF_UE_MAX-1 // if (pusch_active == 0) { if (abstraction_flag == 0) { // LOG_D(PHY,"[eNB] Frame %d, subframe %d Doing I0_measurements\n", // (((subframe)==9)?-1:0) + phy_vars_eNB->proc[sched_subframe].frame_tx,subframe); lte_eNB_I0_measurements(phy_vars_eNB, subframe, 0, phy_vars_eNB->first_run_I0_measurements); phy_vars_eNB->first_run_I0_measurements = 0; } #ifdef PHY_ABSTRACTION else { lte_eNB_I0_measurements_emul(phy_vars_eNB, sect_id); } #endif //} #ifdef EMOS phy_procedures_emos_eNB_RX(subframe,phy_vars_eNB); #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX,0); stop_meas(&phy_vars_eNB->phy_proc_rx); } #undef DEBUG_PHY_PROC #ifdef Rel10 int phy_procedures_RN_eNB_TX(unsigned char last_slot, unsigned char next_slot, relaying_type_t r_type) { int do_proc=0;// do nothing switch(r_type) { case no_relay: do_proc= no_relay; // perform the normal eNB operation break; case multicast_relay: if (((next_slot >>1) < 6) || ((next_slot >>1) > 8)) do_proc = 0; // do nothing else // SF#6, SF#7 and SF#8 do_proc = multicast_relay; // do PHY procedures eNB TX break; default: // should'not be here LOG_W(PHY,"Not supported relay type %d, do nothing\n", r_type); do_proc=0; break; } return do_proc; } #endif void phy_procedures_eNB_lte(unsigned char subframe,PHY_VARS_eNB **phy_vars_eNB,uint8_t abstraction_flag, relaying_type_t r_type, PHY_VARS_RN *phy_vars_rn) { #if defined(ENABLE_ITTI) MessageDef *msg_p; const char *msg_name; instance_t instance; unsigned int Mod_id; int result; #endif int CC_id=0; /* if (phy_vars_eNB->proc[sched_subframe].frame_tx >= 1000) mac_xface->macphy_exit("Exiting after 1000 Frames\n"); */ VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB, phy_vars_eNB[0]->proc[subframe].frame_tx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_LTE,1); start_meas(&phy_vars_eNB[0]->phy_proc); #if defined(ENABLE_ITTI) do { // Checks if a message has been sent to PHY sub-task itti_poll_msg (TASK_PHY_ENB, &msg_p); if (msg_p != NULL) { msg_name = ITTI_MSG_NAME (msg_p); instance = ITTI_MSG_INSTANCE (msg_p); Mod_id = instance; switch (ITTI_MSG_ID(msg_p)) { # if ENABLE_RAL case TIMER_HAS_EXPIRED: // check if it is a measurement timer { hashtable_rc_t hashtable_rc; hashtable_rc = hashtable_is_key_exists(PHY_vars_eNB_g[Mod_id][0]->ral_thresholds_timed, (uint64_t)(TIMER_HAS_EXPIRED(msg_p).timer_id)); if (hashtable_rc == HASH_TABLE_OK) { phy_eNB_lte_check_measurement_thresholds(instance, (ral_threshold_phy_t*)TIMER_HAS_EXPIRED(msg_p).arg); } } break; case PHY_MEAS_THRESHOLD_REQ: #warning "TO DO LIST OF THRESHOLDS" LOG_D(PHY, "[ENB %d] Received %s\n", Mod_id, msg_name); { ral_threshold_phy_t* threshold_phy_p = NULL; int index, res; long timer_id; hashtable_rc_t hashtable_rc; switch (PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.th_action) { case RAL_TH_ACTION_CANCEL_THRESHOLD: break; case RAL_TH_ACTION_SET_NORMAL_THRESHOLD: case RAL_TH_ACTION_SET_ONE_SHOT_THRESHOLD: for (index = 0; index < PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.num_thresholds; index++) { threshold_phy_p = calloc(1, sizeof(ral_threshold_phy_t)); threshold_phy_p->th_action = PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.th_action; memcpy(&threshold_phy_p->link_param.link_param_type, &PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type, sizeof(ral_link_param_type_t)); memcpy(&threshold_phy_p->threshold, &PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.thresholds[index], sizeof(ral_threshold_t)); switch (PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.union_choice) { case RAL_LINK_CFG_PARAM_CHOICE_TIMER_NULL: switch (PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type.choice) { case RAL_LINK_PARAM_TYPE_CHOICE_GEN: SLIST_INSERT_HEAD( &PHY_vars_eNB_g[Mod_id][0]->ral_thresholds_gen_polled[PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type._union.link_param_gen], threshold_phy_p, ral_thresholds); break; case RAL_LINK_PARAM_TYPE_CHOICE_LTE: SLIST_INSERT_HEAD( &PHY_vars_eNB_g[Mod_id][0]->ral_thresholds_lte_polled[PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type._union.link_param_lte], threshold_phy_p, ral_thresholds); break; default: LOG_E(PHY, "[ENB %d] BAD PARAMETER cfg_param.link_param_type.choice %d in %s\n", Mod_id, PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type.choice, msg_name); } break; case RAL_LINK_CFG_PARAM_CHOICE_TIMER: res = timer_setup( (uint32_t)(PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param._union.timer_interval/1000),//uint32_t interval_sec, (uint32_t)(PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param._union.timer_interval%1000),//uint32_t interval_us, TASK_PHY_ENB, instance, TIMER_PERIODIC, threshold_phy_p, &timer_id); if (res == 0) { hashtable_rc = hashtable_insert(PHY_vars_eNB_g[Mod_id][0]->ral_thresholds_timed, (uint64_t )timer_id, (void*)threshold_phy_p); if (hashtable_rc == HASH_TABLE_OK) { threshold_phy_p->timer_id = timer_id; } else { LOG_E(PHY, "[ENB %d] %s: Error in hashtable. Could not configure threshold index %d \n", Mod_id, msg_name, index); } } else { LOG_E(PHY, "[ENB %d] %s: Could not configure threshold index %d because of timer initialization failure\n", Mod_id, msg_name, index); } break; default: // already checked in RRC, should not happen here LOG_E(PHY, "[ENB %d] BAD PARAMETER cfg_param.union_choice %d in %s\n", Mod_id, PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.union_choice, msg_name); } } break; default: LOG_E(PHY, "[ENB %d] BAD PARAMETER th_action value %d in %s\n", Mod_id, PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.th_action, msg_name); } } break; # endif /* Messages from eNB app */ case PHY_CONFIGURATION_REQ: LOG_I(PHY, "[eNB %d] Received %s\n", instance, msg_name); /* TODO */ break; default: LOG_E(PHY, "[ENB %d] Received unexpected message %s\n", Mod_id, msg_name); break; } result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } } while(msg_p != NULL); #endif for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { if ((((phy_vars_eNB[CC_id]->lte_frame_parms.frame_type == TDD)&& (subframe_select(&phy_vars_eNB[CC_id]->lte_frame_parms,phy_vars_eNB[CC_id]->proc[subframe].subframe_tx)==SF_DL))|| (phy_vars_eNB[CC_id]->lte_frame_parms.frame_type == FDD))) { #ifdef Rel10 if (phy_procedures_RN_eNB_TX(phy_vars_eNB[CC_id]->proc[subframe].subframe_rx, phy_vars_eNB[CC_id]->proc[subframe].subframe_tx, r_type) != 0 ) #endif phy_procedures_eNB_TX(subframe,phy_vars_eNB[CC_id],abstraction_flag,r_type,phy_vars_rn); } if ((((phy_vars_eNB[CC_id]->lte_frame_parms.frame_type == TDD )&& (subframe_select(&phy_vars_eNB[CC_id]->lte_frame_parms,phy_vars_eNB[CC_id]->proc[subframe].subframe_rx)==SF_UL)) || (phy_vars_eNB[CC_id]->lte_frame_parms.frame_type == FDD))) { phy_procedures_eNB_RX(subframe,phy_vars_eNB[CC_id],abstraction_flag,r_type); } if (subframe_select(&phy_vars_eNB[CC_id]->lte_frame_parms,phy_vars_eNB[CC_id]->proc[subframe].subframe_tx)==SF_S) { #ifdef Rel10 if (phy_procedures_RN_eNB_TX(subframe, subframe, r_type) != 0 ) #endif phy_procedures_eNB_TX(subframe,phy_vars_eNB[CC_id],abstraction_flag,r_type,phy_vars_rn); } if ((subframe_select(&phy_vars_eNB[CC_id]->lte_frame_parms,phy_vars_eNB[CC_id]->proc[subframe].subframe_rx)==SF_S)) { phy_procedures_eNB_S_RX(subframe,phy_vars_eNB[CC_id],abstraction_flag,r_type); } phy_vars_eNB[CC_id]->proc[subframe].frame_tx++; phy_vars_eNB[CC_id]->proc[subframe].frame_rx++; if (phy_vars_eNB[CC_id]->proc[subframe].frame_tx==MAX_FRAME_NUMBER) // defined in impl_defs_top.h phy_vars_eNB[CC_id]->proc[subframe].frame_tx=0; if (phy_vars_eNB[CC_id]->proc[subframe].frame_rx==MAX_FRAME_NUMBER) phy_vars_eNB[CC_id]->proc[subframe].frame_rx=0; } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_LTE,0); stop_meas(&phy_vars_eNB[0]->phy_proc); }